如何在多重索引Pandas数据框中按组更新前N行的值?

3 投票
2 回答
4783 浏览
提问于 2025-04-18 13:42

我正在尝试更新一个多重索引的数据表中的前N行,但在寻找解决办法时遇到了一些困难,所以我想发个帖子来请教一下。

下面是我的示例代码:

# Imports
import numpy as np
import pandas as pd

# Set Up Data Frame
dates = pd.date_range('1/1/2000', periods=8)
df = pd.DataFrame(np.random.randn(8, 4), columns=['A', 'B', 'C', 'D'])
df['DATE'] = dates
df['CATEGORY'] = ['A','B','A','B','A','B','A','B']

# Set Index
df.set_index(['CATEGORY','DATE'],inplace=True)
df.sort(inplace=True)

# Get First Two Rows of Each Category
df.groupby(level=0).apply(lambda x: x.iloc[0:2])

# Set The Value of Column 'C' Equal to Zero
# ???

我已经能用“iloc”选择到这些行了,但接下来我不太确定怎么把“C”这一列的值设为零。感觉我可能走错了方向。希望能得到一些帮助。谢谢!

2 个回答

1

通常,当你需要改变某些值,而不仅仅是选择它们时,你不能仅仅使用lambda函数,因为它们只允许选择。

一个非常简单的做法是

def replace_first(group):
    group.iloc[0:2] = 99
    return group

然后你只需要这样做

In[144]: df.groupby(level=0).apply(replace_first)
Out[144]: 
                             A          B          C          D
CATEGORY DATE                                                  
A        2000-01-01  99.000000  99.000000  99.000000  99.000000
         2000-01-03  99.000000  99.000000  99.000000  99.000000
         2000-01-05   0.458031   1.959409   0.622295   0.959019
         2000-01-07   0.934521  -2.016685   1.046456   1.489070
B        2000-01-02  99.000000  99.000000  99.000000  99.000000
         2000-01-04  99.000000  99.000000  99.000000  99.000000
         2000-01-06  -0.117322  -1.664436   1.582124   0.486796
         2000-01-08  -0.225379   0.794846  -0.021214  -0.510768
2

这样做怎么样呢?首先定义一个函数,这个函数接收一个数据表(dataframe),然后把前面 x 条记录替换成一个指定的值。

def replace_first_x(group_df, x, value):
    group_df.iloc[:x, :] = value
    return group_df

接着,把这个函数传入 groupby 对象,并使用 apply 方法。

In [97]: df.groupby(level=0).apply(lambda df: replace_first_x(df, 2, 9999))
Out[97]: 
                               A            B            C            D
CATEGORY DATE                                                          
A        2000-01-01  9999.000000  9999.000000  9999.000000  9999.000000
         2000-01-03  9999.000000  9999.000000  9999.000000  9999.000000
         2000-01-05     1.590503     0.948911    -0.268071     0.622280
         2000-01-07    -0.493866     1.222231     0.125037     0.071064
B        2000-01-02  9999.000000  9999.000000  9999.000000  9999.000000
         2000-01-04  9999.000000  9999.000000  9999.000000  9999.000000
         2000-01-06     1.663430    -1.170716     2.044815    -2.081035
         2000-01-08     1.593104     0.108531    -1.381218    -0.517312

撰写回答