Pandas DataFrame有4列:
col1 col2 col3 col4
0 orange NaN NaN NaN
1 NaN tomato NaN NaN
2 NaN NaN apple NaN
3 NaN NaN NaN carrot
4 NaN potato NaN NaN
每行只包含一个字符串值,该值可能出现在任何列中。该行中的其他列是NaN。我想创建一个包含字符串值的列:
col5
0 orange
1 tomato
2 apple
3 carrot
4 potato
最明显的方法如下:
data['col5'] = data.col1.astype(str) + data.col2.astype(str)...
并删除" NaN"来自输出字符串,但它很混乱,肯定会导致错误。
Pandas是否提供了这样做的简单方法?
答案 0 :(得分:2)
这是一种方式,apply
和first_valid_index
:
In [11]: df.apply(lambda x: x[x.first_valid_index()], axis=1)
Out[11]:
0 orange
1 tomato
2 apple
3 carrot
4 potato
dtype: object
要有效地获得这些,你可能会陷入困境:
In [21]: df.values.ravel()[np.arange(0, len(df.index) * len(df.columns), len(df.columns)) + np.argmax(df.notnull().values, axis=1)]
Out[21]: array(['orange', 'tomato', 'apple', 'carrot', 'potato'], dtype=object)
注意:如果您拥有所有NaN的行,则两者都会失败,您应该将其过滤掉(例如使用dropna
)。
答案 1 :(得分:2)
另一种方式(假设每列包含一个字符串值,余数为NaN
,而不是"NaN"
)将是fillna
然后使用max
:
>>> df.fillna('').max(axis=1)
0 orange
1 tomato
2 apple
3 carrot
4 potato
dtype: object
答案 2 :(得分:0)
跨行元素映射过滤函数应该这样做。
data['new_col'] = list(data.apply(lambda row: filter(lambda elem: not pd.isnull(elem), row)[0]))