2017-08-28 28 views
6

这里有一个数据帧:为什么df.apply(元组)工作,但没有df.apply(名单)?

A B C 
0 6 2 -5 
1 2 5 2 
2 10 3 1 
3 -5 2 8 
4 3 6 2 

我可以检索一列基本上是从原来的df使用df.apply列的元组:

out = df.apply(tuple, 1) 
print(out) 

0 (6, 2, -5) 
1  (2, 5, 2) 
2 (10, 3, 1) 
3 (-5, 2, 8) 
4  (3, 6, 2) 
dtype: object 

但是,如果我想的值的列表,而不是一个他们中的元组,我不能这样做,因为它并没有给我什么,我想到:

out = df.apply(list, 1) 
print(out) 

    A B C 
0 6 2 -5 
1 2 5 2 
2 10 3 1 
3 -5 2 8 
4 3 6 2 

相反,我的东东d要做的事:

out = pd.Series(df.values.tolist()) 
print(out) 

0 [6, 2, -5] 
1  [2, 5, 2] 
2 [10, 3, 1] 
3 [-5, 2, 8] 
4  [3, 6, 2] 
dtype: object 

为什么我不能用df.apply(list, 1)得到我想要的?


附录一些可能的解决方法的

时序:

df_test = pd.concat([df] * 10000, 0) 

%timeit pd.Series(df.values.tolist()) # original workaround 
10000 loops, best of 3: 161 µs per loop 

%timeit df.apply(tuple, 1).apply(list, 1) # proposed by Alexander 
1000 loops, best of 3: 615 µs per loop 
+0

奇怪的行为。 'df.apply(tuple,1).apply(list)'作为解决方法? – Alexander

+0

@Alexander可能的,但速度缓慢。 :(增加了一些时机。 –

+3

,在您有列表对象的数据帧的时候,你已经差不多放弃了速度和效率都希望反正...注意,'.apply'只是围绕一个Python的包装为-loop,因此就使用'iterrows'一个for循环自己,这将可能是*比任何'.apply'方法快*。 –

回答

3

罪魁祸首是here。随着func=tuple它的工作原理,但使用func=list从编译的模块lib.reduce内引发了一个异常:

ValueError: ('function does not reduce', 0) 

正如你所看到的,他们捕捉到了异常,但也懒得去处理它。

即使没有太宽泛的除外条款,这是熊猫中的一个错误。您可以尝试提高它自己的跟踪,但类似的问题已经被封闭,不会修复或欺骗的一番风味。

16321: weird behavior using apply() creating list based on current columns

15628: Dataframe.apply does not always return a Series when reduce=True

这后一个问题得到了关闭,然后重新打开,和几个月前转换成文档增强请求,现在似乎被用作任何相关问题的倾销地。

想必它不是一个高优先级,因为作为piRSquared commented(和熊猫维护者commented the same之一),你是一个列表理解更好:

pd.Series([list(x) for x in df.itertuples(index=False)]) 

通常apply将使用numpy ufunc或类似。

+0

非常感谢。我会研究这些链接。 –

相关问题