小能豆

访问同一 DataFrame 列中的先前值

py

这是我的代码:

a = pd.DataFrame([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], columns=['A', 'B'])

print(a)

a['C'] = 1 # or np.nan or is there a way to avoid this?

b = lambda i : i['A'] + i['B'] + i['C'] # actually what is needed if to access a previous element, like i['C'].shift()

a['C'] = a.apply(b, axis=1)

print(a)

它可以正常工作,但是在 lambda 中,我想要访问i['C'].shift(1),但如果以这种方式使用它,我会得到以下异常;

Traceback (most recent call last):
  File "C:\Users\Development\workspace\TestPython\TestPython.py", line 31, in <module>
    a['C'] = a.apply(b, axis=1)
  File "C:\Program Files\Python36\lib\site-packages\pandas\core\frame.py", line 4262, in apply
    ignore_failures=ignore_failures)
  File "C:\Program Files\Python36\lib\site-packages\pandas\core\frame.py", line 4358, in _apply_standard
    results[i] = func(v)
  File "C:\Users\Development\workspace\TestPython\TestPython.py", line 29, in <lambda>
    b = lambda i : i['A'] + i['B'] + i['C'].shift() # actually what is needed if to access a previous element, like i['C'].shift()
AttributeError: ("'numpy.int64' object has no attribute 'shift'", 'occurred at index 0')

而且a['C'] = 1如果可能的话,我想避免初始化,这意味着 a[‘C’] 是在此操作中添加的新列。

有什么建议或其他方法可以实现这一目标吗?


阅读 23

收藏
2024-12-04

共1个答案

小能豆

你的问题是尝试在 apply 中访问 shift() 方法,但你遇到了 AttributeError,因为在 apply 中,i 是每一行的 Series 对象,而不是整个 DataFrame。因此,i['C'] 变成了一个单个值而不是 Series,所以你不能直接对它使用 shift()

解决方法:

  1. 使用 shift() 访问前一个元素:
    你可以避免使用 apply() 来访问前一个元素。shift() 方法是 DataFrame 和 Series 的内置方法,应该直接在列上操作,而不是在 apply() 中。

  2. 如何避免初始化列:
    你可以先不给 C 列赋值,而是直接通过 shift() 计算前一个元素的值。这里是如何做到这一点:

代码示例:

import pandas as pd

# 创建 DataFrame
a = pd.DataFrame([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]], columns=['A', 'B'])
print(a)

# 使用 shift() 来计算列 C 的值
a['C'] = a['A'] + a['B'] + a['C'].shift(1)

print(a)

解释:

  • 在上述代码中,a['C'] 是通过前一行的 C 值来计算的。我们没有提前初始化列 C,而是通过 shift(1) 获取前一行的值。如果没有前一行(如第一行),NaN 会被赋值。

注意:

  • shift(1) 是一个非常有用的 Pandas 方法,它将 Series 或 DataFrame 的所有数据按指定的步长移动。这里 shift(1) 表示将 C 列的值向下移动一行,因此第一行的 C 列将是 NaN

进一步解释:

  • 你不再需要通过 apply 函数来访问前一行的值。直接在 DataFrame 的列上操作可以显著提高效率。
  • 如果你不想在第一行出现 NaN,可以使用 fillna 或其他方式来填充:
a['C'] = a['A'] + a['B'] + a['C'].shift(1).fillna(0)

这样,NaN 将被 0 替代。

总结:

  1. 你应该避免在 apply() 中使用 shift(),因为 shift() 需要在列(Series)上进行操作。
  2. 直接使用 shift() 在列上计算前一行的值,避免了先初始化列。
2024-12-04