ayh*_*han 6 python dataframe pandas
我想弄清楚如何将累积函数应用于对象。对于数字,有几种替代方法,例如cumsum
和cumcount
。还有df.expanding可以与apply
. 但是我传递给的函数apply
不适用于对象。
import pandas as pd
df = pd.DataFrame({"C1": [1, 2, 3, 4],
"C2": [{"A"}, {"B"}, {"C"}, {"D"}],
"C3": ["A", "B", "C", "D"],
"C4": [["A"], ["B"], ["C"], ["D"]]})
df
Out:
C1 C2 C3 C4
0 1 {A} A [A]
1 2 {B} B [B]
2 3 {C} C [C]
3 4 {D} D [D]
Run Code Online (Sandbox Code Playgroud)
在数据框中,我有整数值、集合、字符串和列表。现在,如果我尝试expanding().apply(sum)
我有累积总和:
df.expanding().apply(sum)
Out[69]:
C1 C2 C3 C4
0 1.0 {A} A [A]
1 3.0 {B} B [B]
2 6.0 {C} C [C]
3 10.0 {D} D [D]
Run Code Online (Sandbox Code Playgroud)
我的期望是,由于总和是在列表和字符串上定义的,我会得到这样的结果:
C1 C2 C3 C4
0 1.0 {A} A [A]
1 3.0 {B} AB [A, B]
2 6.0 {C} ABC [A, B, C]
3 10.0 {D} ABCD [A, B, C, D]
Run Code Online (Sandbox Code Playgroud)
我也尝试过这样的事情:
df.expanding().apply(lambda r: reduce(lambda x, y: x+y**2, r))
Out:
C1 C2 C3 C4
0 1.0 {A} A [A]
1 5.0 {B} B [B]
2 14.0 {C} C [C]
3 30.0 {D} D [D]
Run Code Online (Sandbox Code Playgroud)
它按我的预期工作:先前的结果是x
,当前行值为y
。但是我不能减少使用x.union(y)
,例如。
所以,我的问题是:expanding
我可以在对象上使用任何替代方法吗?该示例只是为了表明它expanding().apply()
不适用于对象数据类型。我正在寻找支持将函数应用于这两个输入的通用解决方案:先前的结果和当前元素。
事实证明这是无法做到的。
继续相同的样本:
def burndowntheworld(ser):
print('Are you sure?')
return ser/0
df.select_dtypes(['object']).expanding().apply(burndowntheworld)
Out:
C2 C3 C4
0 {A} A [A]
1 {B} B [B]
2 {C} C [C]
3 {D} D [D]
Run Code Online (Sandbox Code Playgroud)
如果列的类型是对象,则永远不会调用该函数。大熊猫没有适用于对象的替代方案。对于rolling().apply()
.
从某种意义上说,这是一件好事,因为expanding.apply
自定义函数的复杂度为 O(n**2)。对于 等特殊情况cumsum
,ewma
操作的递归性质可以将复杂性降低到线性时间,但在最一般的情况下,它应该计算前 n 个元素的函数,然后是前 n+1 个元素,依此类推。因此,特别是对于仅依赖于当前值和函数先前值的函数,扩展是非常低效的。更不用说在 DataFrame 中存储列表或集合从来都不是一个好主意。
所以答案是:如果您的数据不是数字并且函数依赖于先前的结果和当前元素,只需使用 for 循环。无论如何它会更有效率。
归档时间: |
|
查看次数: |
825 次 |
最近记录: |