问题
我有一个看起来像这样的数据框:
Key Var ID_1 Var_1 ID_2 Var_2 ID_3 Var_3
1 True 1.0 True NaN NaN 5.0 True
2 True NaN NaN 4.0 False 7.0 True
3 False 2.0 False 5.0 True NaN NaN
每行正好有2个非空数据集(ID / Var),其余三分之一保证为空。我想做的是通过删除丢失的元素来“压缩”数据框。
期望的输出
Key Var First_ID First_Var Second_ID Second_Var
1 True 1 True 5 True
2 True 4 False 7 True
3 False 2 False 5 True
只要保持Id / Var对,顺序就不重要。
当前解决方案
下面是我有一个可行的解决方案:
import pandas as pd
import numpy as np
data = pd.DataFrame({'Key': [1, 2, 3], 'Var': [True, True, False], 'ID_1':[1, np.NaN, 2],
'Var_1': [True, np.NaN, False], 'ID_2': [np.NaN, 4, 5], 'Var_2': [np.NaN, False, True],
'ID_3': [5, 7, np.NaN], 'Var_3': [True, True, np.NaN]})
sorted_columns = ['Key', 'Var', 'ID_1', 'Var_1', 'ID_2', 'Var_2', 'ID_3', 'Var_3']
data = data[sorted_columns]
output = np.empty(shape=[data.shape[0], 6], dtype=str)
for i, *row in data.itertuples():
output[i] = [element for element in row if np.isfinite(element)]
print(output)
[['1' 'T' '1' 'T' '5' 'T']
['2' 'T' '4' 'F' '7' 'T']
['3' 'F' '2' 'F' '5' 'T']]
这是可以接受的,但并不理想。我可以不用列名,但是我的大问题是必须将数组内的数据转换为字符串,以避免将布尔值转换为数字。
还有其他解决方案在保存数据方面做得更好吗?如果结果是熊猫数据框,则加分。
有一个简单的解决方案,即将nans推向右侧并在轴1上放下nans。即
ndf = data.apply(lambda x : sorted(x,key=pd.isnull),1).dropna(1)
输出:
密钥Var ID_1 Var_1 ID_2 Var_2 0 1 True 1 True 5 True 1 2 True 4 False 7 True 2 3 False 2 False 5 True
希望能帮助到你。
从Divakar一个numpy的解决方案在这里为10倍速度即
def mask_app(a):
out = np.full(a.shape,np.nan,dtype=a.dtype)
mask = ~np.isnan(a.astype(float))
out[np.sort(mask,1)[:,::-1]] = a[mask]
return out
ndf = pd.DataFrame(mask_app(data.values),columns=data.columns).dropna(1)
密钥Var ID_1 Var_1 ID_2 Var_2 0 1 True 1 True 5 True 1 2 True 4 False 7 True 2 3 False 2 False 5 True
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句