假设我有一个多列数据框,我希望实现一个瀑布式算法,如果它存在则采用第一列,然后查看第二列(如果不存在),如果不存在则采用值在第三列中,依此类推,如果在最后一列中丢失,则采用默认值(比如零)。我有办法这样做,包括添加一系列向量操作(见下文),但它似乎没有很好地扩展到更多列。当然,我可以通过行嵌套循环(非常unpythonic - 对吗?)
frame = pd.DataFrame(np.arange(15).reshape((5,3)),index=['a','b','c','d','e'],columns=['X','Y', 'Z'])
#Make some missing values
frame['X'].ix[0:2] = None
frame['Y'].ix[1:4] = None
frame['Z'].ix[3:5] = None
#This is my kludgy waterfall for the three column case.
frame['Waterfall'] = frame['X'].fillna(0) + frame['Y'].fillna(0) * frame['X'].isnull() + frame['Z'].fillna(0) * (frame['X'].isnull() & frame['Y'].isnull())
我希望这个问题的解决方案可以很好地扩展到任意长度的瀑布。如果它可能更像Pythonic那将是伟大的。理想情况下,它是一个函数,它将列标签的有序列表作为参数采用数据帧并返回所需的值。
感谢您的帮助。
答案 0 :(得分:2)
首先,不要将None
用作缺失的数据值。这会强制所有列到object
dtype,这将很慢。使用nan
代替(这使得所有内容doubles
所以请注意浮点内容。
我对bfill
使用fillna()
方法:
In [26]: frame.fillna(method='bfill', axis=1)['X'].fillna(0)
Out[26]:
a 1
b 5
c 6
d 9
e 12
Name: X, dtype: float64
性能:
In [27]: %timeit frame['X'].fillna(0) + frame['Y'].fillna(0) * frame['X'].isnull() + frame['Z'].fillna(0) * (frame['X'].isnull() & fra
me['Y'].isnull())
1000 loops, best of 3: 776 µs per loop
In [28]: %timeit frame.fillna(method='bfill', axis=1)['X']
10000 loops, best of 3: 138 µs per loop