Я изо всех сил пытаюсь понять странное взаимодействие, которое Панда делает, когда вы назначаете DataFrame для столбца.Основанный на методологии разделения-применения-объединения, иногда применение groupby возвращает ряд Pandas (что я хочу), а иногда возвращает DataFrame (если групповая группировка - это все одна группа).
Я пыталсяконтролируйте это, потому что Pandas выдает ошибку, когда вы пытаетесь назначить DataFrame столбцу DataFrame, поэтому я пытаюсь назначить и затем сложить DataFrame, если он выдает ошибку.Взаимодействие, которое заключается в том, что если столбец, который вы пытаетесь назначить, уже существует, назначение работает, но просто дает все NaN (или иногда я видел одно значение, отличное от NaN).Если столбец не существует, присваивание выдает ошибку, как и ожидалось, и я исключил, что это будет работать правильно.
Может кто-нибудь объяснить это способом, который имеет смысл, поэтому я знаю, как думатьоб этом в будущем?Само исправление относительно простое - я могу просто проверить, является ли промежуточный результат DataFrame или Series, но я думал, что Python обычно должен просить прощения вместо проверки на разрешение.
Вот мой код ирезультаты:
df = pd.DataFrame({'type1': 'a', 'type2': ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'b'],
'index': range(8), 'arpi': np.random.normal(loc=10, size=8), 'cumarpi': np.random.randint(0,100,8)},
columns=['type1', 'type2', 'index', 'arpi', 'cumarpi'])
print df
type1 type2 index arpi cumarpi
0 a a 0 11.973688 76
1 a a 1 9.788948 66
2 a a 2 9.371912 59
3 a a 3 11.116768 32
4 a b 4 10.347337 17
5 a b 5 11.966324 76
6 a b 6 9.272982 73
7 a b 7 8.865021 34
def getCumArpi(df, group_variables, arpi_var, cumapri_var_new='cumarpi'):
"""get cumarpi variable for different types of group variables"""
df = df.copy(deep=True)
if len(group_variables) == 0:
# no groupby variables
df[cumapri_var_new] = np.cumsum(df[arpi_var])
else:
cumarpi = df.groupby(group_variables, group_keys=False).apply(lambda s: np.cumsum(s[arpi_var]))
print cumarpi
try:
# groupby apply returns Series
df[cumapri_var_new] = cumarpi
except:
# groupby apply returns DataFrame
df[cumapri_var_new] = cumarpi.stack().reset_index(drop=True)
return df
df_1 = getCumArpi(df, ['type1'], 'arpi')
print df_1
# returns a DataFrame and inserts it as a column anyways if using a column that already exists, but inserts it as all NaNs
arpi 0 1 2 3 4 5 6 7
type1
a 11.973688 21.762636 31.134548 42.251316 52.598654 64.564978 73.83796 82.702981
type1 type2 index arpi cumarpi
0 a a 0 11.973688 NaN
1 a a 1 9.788948 NaN
2 a a 2 9.371912 NaN
3 a a 3 11.116768 NaN
4 a b 4 10.347337 NaN
5 a b 5 11.966324 NaN
6 a b 6 9.272982 NaN
7 a b 7 8.865021 NaN
df_2 = getCumArpi(df, ['type1'], 'arpi', cumapri_var_new='cumarpi_new')
print df_2
# returns a DataFrame but throws an error when inserting as a column, this triggers the except clause and correctly stacks it into a Series
arpi 0 1 2 3 4 5 6 7
type1
a 11.973688 21.762636 31.134548 42.251316 52.598654 64.564978 73.83796 82.702981
type1 type2 index arpi cumarpi cumarpi_new
0 a a 0 11.973688 76 11.973688
1 a a 1 9.788948 66 21.762636
2 a a 2 9.371912 59 31.134548
3 a a 3 11.116768 32 42.251316
4 a b 4 10.347337 17 52.598654
5 a b 5 11.966324 76 64.564978
6 a b 6 9.272982 73 73.837960
7 a b 7 8.865021 34 82.702981
df_3 = getCumArpi(df, ['type1', 'type2'], 'arpi')
print df_3
# returns a Series because the split-apply-combine methodology groups into more than one group and inserts correctly
0 11.973688
1 21.762636
2 31.134548
3 42.251316
4 10.347337
5 22.313661
6 31.586644
7 40.451665
Name: arpi, dtype: float64
type1 type2 index arpi cumarpi
0 a a 0 11.973688 11.973688
1 a a 1 9.788948 21.762636
2 a a 2 9.371912 31.134548
3 a a 3 11.116768 42.251316
4 a b 4 10.347337 10.347337
5 a b 5 11.966324 22.313661
6 a b 6 9.272982 31.586644
7 a b 7 8.865021 40.451665