Как обновить значение в первых N строках по группе в многоиндексном кадре данных Pandas?

Я пытаюсь обновить первые 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» равным нулю. Хотя, похоже, я неправильно к этому отношусь. Любая помощь будет принята с благодарностью. Спасибо!


person slee    schedule 17.07.2014    source источник


Ответы (2)


Как насчет этого - сначала определите функцию, которая принимает кадр данных и заменяет первые 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
person chrisb    schedule 17.07.2014
comment
Спасибо chrisb/FooBar, это именно то, что я искал. Также оцените эмпирическое правило FooBar - это полезно. - person slee; 17.07.2014

Как правило, всякий раз, когда вам нужно изменить значения, а не просто выбрать их, вы не можете использовать только функцию 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
person FooBar    schedule 17.07.2014
comment
Что, если вы хотите изменить значение только одного столбца? - person user1462620; 31.01.2018