[英]Combine multiple categorical columns into one, when each row has only one non-NaN value, in Pandas
我有
import pandas as pd
import numpy as np
df = pd.DataFrame({"x": ["red", "blue", np.nan, np.nan, np.nan, np.nan, np.nan, ],
"y": [np.nan, np.nan, np.nan, 'cold', 'warm', np.nan, np.nan, ],
"z": [np.nan, np.nan, np.nan, np.nan, np.nan, 'charm', 'strange'],
}).astype("category")
给予
x y z
0 red NaN NaN
1 blue NaN NaN
2 NaN NaN NaN
3 NaN cold NaN
4 NaN warm NaN
5 NaN NaN charm
6 NaN NaN strange
我想添加一个新的分类列,其中包含未排序的值 red、blue、hot、cold、warm、charm、strange,并适当填写。 我有很多这样的专栏,不只是三个。
一些可能性:
astype(str)
并连接然后重新创建一个分类union_categoricals
创建一个新的分类类型,然后将每一列转换为该类型? 然后连续fillna()
他们?我无法让这些或其他任何东西工作。
注意:在定义df
时使用.astype(pd.CategoricalDtype(ordered=True))
代替.astype("category")
也适用于以下答案。
新方案
为了用于大型数据集,以下解决方案可能更有效:
def my_fun(x):
m = ~ pd.isnull(x)
if m.any():
return x[m]
else:
return np.nan
df['new'] = np.apply_along_axis(my_fun, 1, df.to_numpy())
x y z new
0 red NaN NaN red
1 blue NaN NaN blue
2 NaN NaN NaN NaN
3 NaN cold NaN cold
4 NaN warm NaN warm
5 NaN NaN charm charm
6 NaN NaN strange strange
编辑答案
正如 OP 所指定的,如果有些行的所有值都是np.NaN
,我们可以尝试以下解决方案:
df['new_col'] = df.dropna(how='all').apply(lambda x: x.loc[x.first_valid_index()], axis=1)
df['new_col'] = pd.Categorical(df.new_col)
df
x y z new_col
0 red NaN NaN red
1 blue NaN NaN blue
2 NaN NaN NaN NaN
3 NaN cold NaN cold
4 NaN warm NaN warm
5 NaN NaN charm charm
6 NaN NaN strange strange
试试ffill()
df['col'] = df.ffill(axis=1).iloc[:,-1].astype('category')
或stack()
与groupby()
df['col'] = df.stack().groupby(level=0).first().astype('category')
Output:
x y z col
0 red NaN NaN red
1 blue NaN NaN blue
2 NaN NaN NaN NaN
3 NaN cold NaN cold
4 NaN warm NaN warm
5 NaN NaN charm charm
6 NaN NaN strange strange
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.