在函数内部和外部执行列表串联时,我遇到了一个无法解释的问题。具体来说,我尝试连接函数内部和函数外部的 DataFrame 列名称的列表。外部看起来工作正常,但内部会抛出错误。请参阅下面的示例。
示例:假设我想编写一个函数,返回列的多个滞后,并根据原始列名称为滞后变量分配新名称。我可以做这样的事情:
import pandas as pd
import numpy as np
rng = np.random.default_rng(22222222)
df = pd.DataFrame({'X':rng.random(10)})
print(df)
X
0 0.279384
1 0.838032
2 0.298536
3 0.056188
4 0.532023
5 0.560038
6 0.127512
7 0.322774
8 0.813949
9 0.245242
制作函数:
def lagger(column, lags): #Takes as input a DataFrame column in the form df[colname]
lags = [column.shift(i) for i in range(1, lags+1)]
df = pd.concat(lags, axis=1) #a DataFrame with a column for each lag.
names = [f"{column.name}_L{i}" for i in range(1,lags+1)] #generate new names
df.rename(names, axis='columns', inplace=True)
return df
测试该功能,我收到此错误:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[27], line 1
----> 1 lagger(df['X'], 3)
Cell In[25], line 6
2 lags = [column.shift(i) for i in range(1, lags+1)]
4 df = pd.concat(lags, axis=1) #a DataFrame with a column for each lag.
----> 6 names = [f"{column.name}_L{i}" for i in range(1,lags+1)] #generate new names
8 df.rename(names, axis='columns', inplace=True)
10 return df
TypeError: can only concatenate list (not "int") to list
列表理解出了问题。让我们尝试在函数之外进行类似的理解:
[f"{df['X'].name}_L{i}" for i in range(1,4)]
['X_L1', 'X_L2', 'X_L3']
效果很好!
那么这是怎么回事?为什么这在函数外部有效但在函数内部却不起作用?
需要明确的是,我已经找到了这个答案,它阐明了如何生成多个滞后。我不是问这个。我问在函数内部执行
[f"{column.name}_L{i}" for i in range(1,lags+1)]
与在函数外部执行 [f"{df['X'].name}_L{i}" for i in range(1,4)]
有什么区别?为什么在函数内部会失败?
您用函数中的列表覆盖参数
lags
。因此 range(1, lags+1)
不再起作用。使用另一个名称。另外,您使用 rename
是不正确的,您应该使用 set_axis
:
def lagger(column, lags): #Takes as input a DataFrame column in the form df[colname]
l = [column.shift(i) for i in range(1, lags+1)]
df = pd.concat(l, axis=1) #a DataFrame with a column for each lag.
names = [f"{column.name}_L{i}" for i in range(1, lags+1)] #generate new names
return df.set_axis(names, axis='columns')
lagger(df['X'], 3)