对象/str pandas 数据框列上最频繁的*滚动*值

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

我想要一个新列,其中包含另一个 str/object 列中最频繁的

rolling
值。

          date     name state
0   2024-02-29    Alice    CA
1   2024-02-27      Bob    HI
2   2024-02-29    Cindy    ID
3   2024-02-25      Dan    MT
4   2024-02-29  Elliott    CA
..       ...        ...   ...

我正在尝试获得最频繁的滚动

state
(对于每一行)。

我尝试过不同的组合(和子集)

  • .rolling()
  • .apply()
  • .mode()
  • 来自不同库的mode()
  • 自定义mode()函数

这通常会生成少数错误之一,抱怨该列是非数字的。我明白错误告诉我什么 - 它期望聚合并应用数字函数(

.mean()
.sum()
...) - 但它甚至没有到达
.apply()
函数...

def fail_now(x):
    raise Exception('wow! we made it here!')
>>> df['state'].rolling(window=25).apply(fail_now)
...
pandas.errors.DataError: No numeric types to aggregate
>>> df[['state']].rolling(window=25).apply(fail_now)
...
pandas.errors.DataError: Cannot aggregate non-numeric type: object
>>> df[['state']].rolling(window=25)['state'].apply(fail_now)
...
pandas.errors.DataError: No numeric types to aggregate

我还尝试了多种不同的方法,包括

raw
中的
.apply()
标志,但没有运气

python pandas dataframe apply rolling-computation
1个回答
0
投票

rolling
仅适用于数值,您可以先
factorize
您的数据,然后
map
原始名称:

a, idx = pd.factorize(df['state'])

df['rolling_mode'] = (pd.Series(a, index=df.index)
                        .rolling(3, min_periods=1)    # window=3 for the demo
                        .apply(lambda x: x.mode()[0])
                        .map(dict(enumerate(idx)))
                     )

输出:

         date     name state rolling_mode
0  2024-02-29    Alice    CA           CA
1  2024-02-27      Bob    HI           CA
2  2024-02-29    Cindy    ID           CA
3  2024-02-25      Dan    MT           HI
4  2024-02-29  Elliott    CA           CA
© www.soinside.com 2019 - 2024. All rights reserved.