从Pandas数据帧中的多列构造瀑布算法

时间:2014-04-04 13:11:19

标签: python pandas

假设我有一个多列数据框,我希望实现一个瀑布式算法,如果它存在则采用第一列,然后查看第二列(如果不存在),如果不存在则采用值在第三列中,依此类推,如果在最后一列中丢失,则采用默认值(比如零)。我有办法这样做,包括添加一系列向量操作(见下文),但它似乎没有很好地扩展到更多列。当然,我可以通过行嵌套循环(非常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那将是伟大的。理想情况下,它是一个函数,它将列标签的有序列表作为参数采用数据帧并返回所需的值。

感谢您的帮助。

1 个答案:

答案 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