此代码的行为很奇怪:
import pandas as pd
def calc(row):
print(f"Row: {row.to_list()}")
result = pd.Series({
"sum1": row.col1 + row.col2,
"sum2": row.col2 + row.col3,
"sum3": row.col1 + row.col3,
})
return result
df = pd.DataFrame({"col1":[1,2,3],
"col2":[4,5,6],
"col3":[7,8,9]})
df[["sum12", "sum23", "sum13"]] = df.apply(lambda row: calc(row), axis=1)
print(df)
返回
Row: [1, 4, 7]
Row: [1, 4, 7]
Row: [2, 5, 8]
Row: [3, 6, 9]
col1 col2 col3 sum12 sum23 sum13
0 1 4 7 5 11 8
1 2 5 8 7 13 10
2 3 6 9 9 15 12
第一个问题:
为什么第一行要详细说明两次?
第二个问题可能与第一个相关:
在我的真实代码中,第一行的详细说明花费0.15秒(由time.process_time()
读取),随后的行介于0.53和0.60之间。第一行进行了两次详细说明,第一次是0.15秒,第二次是0.55秒。
原因是什么,因为数据是统一的,numpy
中仅使用calc()
,并且没有条件或数据过滤器?
答案 0 :(得分:1)
这是GroupBy.apply
(熊猫<0.25)和df.apply
(熊猫<1.1)的一个已知问题。对第一组进行两次评估的原因是,apply
想知道它是否可以“优化”计算(有时,apply
可以接收到numpy或cythonized函数是有可能的。)
对于熊猫0.25,此行为已针对GroupBy.apply
进行了修复。参见here。现在有了熊猫1.1,the same behavior will be fixed for df.apply
.
1.1版发布后,您将可以升级,然后您将只看到第一个评估组仅评估一次:
pd.__version__
# '1.1.0.dev0+2004.g8d10bfb6f'
df[["sum12", "sum23", "sum13"]] = df.apply(lambda row: calc(row), axis=1)
print(df)
Row: [1, 4, 7]
Row: [2, 5, 8]
Row: [3, 6, 9]
col1 col2 col3 sum12 sum23 sum13
0 1 4 7 5 11 8
1 2 5 8 7 13 10
2 3 6 9 9 15 12