【问题标题】:TypeError: incompatible index of inserted column with frame index when grouping 2 columnsTypeError:对2列进行分组时,插入列的索引与框架索引不兼容
【发布时间】:2022-02-15 17:19:57
【问题描述】:

我有一个看起来像这样的数据集(+ 其他一些列):

Value         Theme       Country
-1.975767     Weather     China
-0.540979     Fruits      China
-2.359127     Fruits      China
-2.815604     Corona      Brazil
-0.929755     Weather     UK
-0.929755     Weather     UK

我想找到按主题和国家分组后的值的标准偏差(如calculate standard deviation by grouping two columns 此处所述)

df = pd.read_csv('./Brazil.csv')
df['std'] = df.groupby(['themes', 'country'])['value'].std()

但是,目前,我收到此错误:

File /usr/local/Cellar/ipython/8.0.1/libexec/lib/python3.10/site-packages/pandas/core/frame.py:3656, in DataFrame.__setitem__(self, key, value)
   3653     self._setitem_array([key], value)
   3654 else:
   3655     # set column
-> 3656     self._set_item(key, value)

File /usr/local/Cellar/ipython/8.0.1/libexec/lib/python3.10/site-packages/pandas/core/frame.py:3833, in DataFrame._set_item(self, key, value)
   3823 def _set_item(self, key, value) -> None:
   3824     """
   3825     Add series to DataFrame in specified column.
   3826 
   (...)
   3831     ensure homogeneity.
   3832     """
-> 3833     value = self._sanitize_column(value)
   3835     if (
   3836         key in self.columns
   3837         and value.ndim == 1
   3838         and not is_extension_array_dtype(value)
   3839     ):
   3840         # broadcast across multiple columns if necessary
   3841         if not self.columns.is_unique or isinstance(self.columns, MultiIndex):

File /usr/local/Cellar/ipython/8.0.1/libexec/lib/python3.10/site-packages/pandas/core/frame.py:4534, in DataFrame._sanitize_column(self, value)
   4532 # We should never get here with DataFrame value
   4533 if isinstance(value, Series):
-> 4534     return _reindex_for_setitem(value, self.index)
   4536 if is_list_like(value):
   4537     com.require_length_match(value, self.index)

File /usr/local/Cellar/ipython/8.0.1/libexec/lib/python3.10/site-packages/pandas/core/frame.py:10985, in _reindex_for_setitem(value, index)
  10981     if not value.index.is_unique:
  10982         # duplicate axis
  10983         raise err
> 10985     raise TypeError(
  10986         "incompatible index of inserted column with frame index"
  10987     ) from err
  10988 return reindexed_value

TypeError: incompatible index of inserted column with frame index

【问题讨论】:

  • 您不能直接在输入数据框中插入 groupby 聚合的结果。你能提供预期的输出吗?
  • 我想将std的值保存在一个新的col df['std']@mozway
  • 您能否在问题中提供明确的预期输出作为文本?

标签: python pandas dataframe numpy standard-deviation


【解决方案1】:

使用DataFrame.expanding 并通过DataFrame.droplevel 删除新列的第一级应该是更简单的解决方案:

df['std']  = (df.groupby(['Theme', 'Country'])['Value']
                .expanding()
                .std()
                .droplevel([0,1]))
print (df)
      Value    Theme Country       std
0 -1.975767  Weather   China       NaN
1 -0.540979   Fruits   China       NaN
2 -2.359127   Fruits   China  1.285625
3 -2.815604   Corona  Brazil       NaN
4 -0.929755  Weather      UK       NaN
5 -0.929755  Weather      UK  0.000000

【讨论】:

  • 哇,我不知道这个.expanding 方法。感谢您分享酷炫的技术。赞成。
  • @x89 嘿,我认为这是最好的答案。
  • @quasi-human - 与几年前我从另一个答案中学到的完全一样;)所以我会永远记住它;)
  • 你能不能用扩展一点来解释一下这个方法?
  • @x89 - 我认为here 是很好的解释
【解决方案2】:

您可以使用rolling 方法计算每个组的累积标准差。

代码

import pandas as pd

# Create a sample dataframe
import io
text_csv = '''Value,Theme,Country
-1.975767,Weather,China
-0.540979,Fruits,China
-2.359127,Fruits,China
-2.815604,Corona,Brazil
-0.929755,Weather,UK
-0.929755,Weather,UK'''
df = pd.read_csv(io.StringIO(text_csv))

# Calculate cumulative standard deviations
df_std = df.groupby(['Theme', 'Country'], as_index=False)['Value'].rolling(len(df), min_periods=1).std()

# Merge the original df with the cumulative std values
df_std = df.join(df_std.drop(['Theme', 'Country'], axis=1).rename(columns={'Value': 'CorrectedStd'}))

输出

Value Theme Country CorrectedStd
0 -1.97577 Weather China nan
1 -0.540979 Fruits China nan
2 -2.35913 Fruits China 1.28562
3 -2.8156 Corona Brazil nan
4 -0.929755 Weather UK nan
5 -0.929755 Weather UK 0

【讨论】:

  • 我认为这是不正确的,因为 Fruits/china 的标准差值不应该相同。我还使用另一个数据集进行了测试,它对同一主题/国家的所有行显示了相同的校正 STD。每次都应该重新计算
  • 为一个总体定义了一个标准差值。因此,根据定义,在多个 Fruits/China 行之间不可能有不同的 STD 值。也许这不是标准偏差,而是您想要的 Z 分数。见Z-score的定义:en.wikipedia.org/wiki/Standard_score
  • 当我计算一行的标准差时,我想想象它下面没有行。我只想考虑它上面的行。因此,例如,当一个新行进入时,我计算一个新的标准值,这当然会与前一个不同,因为总均值/平方和(用于计算标准)也会改变.你明白我的意思吗?
  • 一个很好的解释。我现在完全明白了。你想要得到的是累积标准偏差。检查我更新的答案。
  • @x89 - 它是expanding 替代方案,它按组滚动。这是组的长度,不像 df 的长度,所以效果很好rolling(len(df)
猜你喜欢
  • 1970-01-01
  • 2017-01-16
  • 2021-10-03
  • 1970-01-01
  • 1970-01-01
  • 2020-03-29
  • 2021-04-30
相关资源
最近更新 更多