【问题标题】:Update pandas dataframe based on slice?基于切片更新熊猫数据框?
【发布时间】:2021-12-30 06:11:23
【问题描述】:

我见过Update pandas dataframe based on slice - 但我找不到我的用例的答案。

考虑这段代码,我有一个包含“通道”和“值”列的起始表:

import sys
if sys.version_info[0] < 3:
    from StringIO import StringIO
else:
    from io import StringIO

import pandas as pd

TESTDATA = StringIO("""channel,value
A,10
A,11
A,12
A,13
B,20
B,22
B,24
B,26
B,28
C,100
C,105
C,110
C,115
C,120
C,125
C,130
""")

mychans = ["A", "B", "C"]

df = pd.read_csv(TESTDATA)
df.insert (2, "value_rel", df["value"] - df["value"][0])

print("Starting:")
print(df.head())

for tchan in mychans:
  this_ch_data = df[df["channel"]==tchan]
  df.loc[this_ch_data.index, "value_rel"] = this_ch_data["value"] - this_ch_data["value"][0]

最后,我想获得带有附加“value_rel”列的同一张表,该列将显示相对于该通道中的第一个值(切片)的值;那就是:

A, 10, 0
A, 11, 1
A, 12, 2
A, 13, 3
B, 20, 0
B, 22, 2
B, 24, 4
B, 26, 6
B, 28, 8
C,100, 0
C,105, 5
...

如果我只在for 循环中使用this_ch_data["value_rel"] = this_ch_data["value"] - this_ch_data["value"][0],我会得到“试图在数据帧的切片副本上设置值”,这是有道理的。

但是,当运行代码时,我得到:

$ python3 test1.py
Starting:
  channel  value  value_rel
0       A     10          0
1       A     11          1
2       A     12          2
3       A     13          3
4       B     20         10
Traceback (most recent call last):
  File "C:/msys64/mingw64/lib/python3.9/site-packages/pandas/core/indexes/base.py", line 3361, in get_loc
    return self._engine.get_loc(casted_key)
  File "pandas/_libs/index.pyx", line 76, in pandas._libs.index.IndexEngine.get_loc
  File "pandas/_libs/index.pyx", line 108, in pandas._libs.index.IndexEngine.get_loc
  File "pandas/_libs/hashtable_class_helper.pxi", line 2131, in pandas._libs.hashtable.Int64HashTable.get_item
  File "pandas/_libs/hashtable_class_helper.pxi", line 2140, in pandas._libs.hashtable.Int64HashTable.get_item
KeyError: 0

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\msys64\tmp\test1.py", line 38, in <module>
    df.loc[this_ch_data.index, "value_rel"] = this_ch_data["value"] - this_ch_data["value"][0]
  File "C:/msys64/mingw64/lib/python3.9/site-packages/pandas/core/series.py", line 942, in __getitem__
    return self._get_value(key)
  File "C:/msys64/mingw64/lib/python3.9/site-packages/pandas/core/series.py", line 1051, in _get_value
    loc = self.index.get_loc(label)
  File "C:/msys64/mingw64/lib/python3.9/site-packages/pandas/core/indexes/base.py", line 3363, in get_loc
    raise KeyError(key) from err
KeyError: 0

那么,如何根据对同一 DataFrame 的(复制的)切片进行的计算来更新此 DataFrame?

【问题讨论】:

    标签: python pandas dataframe slice


    【解决方案1】:

    您可以应用自定义函数将通道组减去组的第一个值。

    df['value_rel'] = df.groupby('channel')['value'].apply(lambda x: x - x.iloc[0])
    print(df)
    
    # Output:
       channel  value  value_rel
    0        A     10          0
    1        A     11          1
    2        A     12          2
    3        A     13          3
    4        B     20          0
    5        B     22          2
    6        B     24          4
    7        B     26          6
    8        B     28          8
    9        C    100          0
    10       C    105          5
    11       C    110         10
    12       C    115         15
    13       C    120         20
    14       C    125         25
    15       C    130         30
    

    【讨论】:

    • 实际上,您确实明白 - 您发布的内容正是我想要实现的 :) 不过接受了另一个答案,因为它解释了索引错误。
    • 没问题。我想确定我的答案是正确的。
    • 没错——但另一个答案也解释了这个错误,我觉得这很好,即使我没有明确要求。
    【解决方案2】:

    您需要使用iloc,因为并非所有tchan都存在索引号0。

    for tchan in mychans:
      this_ch_data = df[df["channel"]==tchan]
      df.loc[this_ch_data.index, "value_rel"] = \
             this_ch_data["value"] - this_ch_data["value"].iloc[0]
    

    也就是说,groupby.transformfirst 是很好的用例。所以不需要循环,你可以这样做

    df['value_rel'] = df['value'] - df.groupby('channel')['value'].transform('first')
    

    【讨论】:

    • 啊,非常感谢 - “索引号 0 并不存在于所有 tchan。”回避了我,正是我需要的解释!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    • 1970-01-01
    • 2017-02-22
    • 2023-01-26
    • 2017-01-19
    • 2020-11-18
    相关资源
    最近更新 更多