为什么在此函数内连接根据 DataFrame 列名称生成的字符串项列表会失败?

问题描述 投票:0回答:1

在函数内部和外部执行列表串联时,我遇到了一个无法解释的问题。具体来说,我尝试连接函数内部和函数外部的 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)]
有什么区别?为什么在函数内部会失败?

pandas function list-comprehension f-string
1个回答
0
投票

您用函数中的列表覆盖参数

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)
© www.soinside.com 2019 - 2024. All rights reserved.