1

Assuming there is a pandas.DataFrame like:

pd.DataFrame([[np.nan,np.nan],[[1,2],[3,4]],[[11,22],[33,44]]],columns=['A','B'])

What's the easiest way to produce 2 pandas.DataFrames that each contains the 1st and 2nd element from every value list in the frame (nan if the position is nan).

pd.DataFrame([[np.nan,np.nan],[1,3],[11,33]],columns=['A','B'])
pd.DataFrame([[np.nan,np.nan],[2,4],[22,44]],columns=['A','B'])

2 Answers 2

1

You can use:

#replace NaN to [] - a bit hack
df = df.mask(df.isnull(), pd.Series([[]] * len(df.columns), index=df.columns), axis=1)
print (df)
          A         B
0        []        []
1    [1, 2]    [3, 4]
2  [11, 22]  [33, 44]

#create new df by each column, concanecate together
df3 = pd.concat([pd.DataFrame(df[col].values.tolist()) for col in df],
                axis=1, 
                keys=df.columns)
print (df3)
      A           B      
      0     1     0     1
0   NaN   NaN   NaN   NaN
1   1.0   2.0   3.0   4.0
2  11.0  22.0  33.0  44.0

#select by xs
df1 = df3.xs(0, level=1, axis=1)
print (df1)
      A     B
0   NaN   NaN
1   1.0   3.0
2  11.0  33.0

df2 = df3.xs(1, level=1, axis=1)
print (df2)
      A     B
0   NaN   NaN
1   2.0   4.0
2  22.0  44.0
Sign up to request clarification or add additional context in comments.

Comments

0

You can do what you need with a function that return the n'th element of each column.

Code:

def row_element(elem_num):
    def func(row):
        ret = []
        for item in row:
            try:
                ret.append(item[elem_num])
            except:
                ret.append(item)
        return ret
    return func

Test Code:

df = pd.DataFrame(
    [[np.nan, np.nan], [[1, 2], [3, 4]], [[11, 22], [33, 44]]],
    columns=['A', 'B'])

print(df)
print(df.apply(row_element(0), axis=1))
print(df.apply(row_element(1), axis=1))

Results:

          A         B
0       NaN       NaN
1    [1, 2]    [3, 4]
2  [11, 22]  [33, 44]

      A     B
0   NaN   NaN
1   1.0   3.0
2  11.0  33.0

      A     B
0   NaN   NaN
1   2.0   4.0
2  22.0  44.0

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.