pandas - 根据列名压缩宽数据
问题描述
有没有一种优雅的方式来做我想要在 Pandas 中做的事情?我的数据看起来像:
df = pd.DataFrame({
'alpha': [1, np.nan, np.nan, np.nan],
'bravo': [np.nan, np.nan, np.nan, -1],
'charlie': [np.nan, np.nan, np.nan, np.nan],
'delta': [np.nan, 1, np.nan, np.nan],
})
print(df)
alpha bravo charlie delta
0 1.0 NaN NaN NaN
1 NaN NaN NaN 1.0
2 NaN NaN NaN NaN
3 NaN -1.0 NaN NaN
我想把它变成类似的东西:
position value
0 alpha 1
1 delta 1
2 NaN NaN
3 bravo -1
因此,对于原始数据中的每一行,我想找到非 NaN 值并检索找到它的列的名称。然后我将列和值存储在名为“位置”和“值”的新列中。
我可以保证原始数据中的每一行都包含零个或一个非 NaN 值。
我唯一的想法是遍历每一行,但我知道这个想法很糟糕,必须有一种更平易近人的方式来做到这一点。我不完全确定如何表达我的问题,所以我在谷歌上搜索想法时遇到了麻烦。感谢您的任何建议!
解决方案
我们可以使用DataFrame.melt
unpivot 您的数据,然后使用sort_values
and drop_duplicates
:
df = (
df.melt(var_name='position')
.sort_values('value')
.drop_duplicates('position', ignore_index=True)
)
position value
0 bravo -1.0
1 alpha 1.0
2 delta 1.0
3 charlie NaN
另一种选择是DataFrame.bfill
在列轴上使用。既然你注意到:
可以保证原始数据中的每一行都恰好包含零个或一个非NaN值
values = df.bfill(axis=1).iloc[:, 0]
dfn = pd.DataFrame({'positions': df.columns, 'values': values})
positions values
0 alpha 1.0
1 bravo 1.0
2 charlie NaN
3 delta -1.0
推荐阅读
- javascript - 将图标图像绑定到它们各自的名称然后渲染
- html - 如何使图像适合其容器 - 动态执行
- java - java.lang.OutOfMemoryError:在 Jmeter 负载测试期间超出了 GC 开销限制
- java - 在android代码上执行model.forward时应用程序崩溃,我不知道为什么?
- vb.net - 将文本写入输出文件时的进度条
- java - BoxCars Java 程序 - 初学者。奇怪的问题:程序不在控制台中运行,但它在 Eclipse 中没有列出任何错误
- python - 为重新采样的分位数值创建单独的 pandas df
- python - 登录后通过网页解析并从表中提取数据
- java - android studio 中的 Firestore 参考
- java - 以十进制格式格式化数字字符串