Понимание индексов и имен столбцов в pandas

#python #pandas

#python #pandas

Вопрос:

Я пытаюсь понять, как обрабатывать индексы и ряды и наоборот при использовании apply. Вот значительно упрощенный пример моей проблемы.

 import pandas as pd 

df = pd.DataFrame({'name':["alice","bob","charlene","alice","bob","charlene","alice","bob","charlene","edna" ],
                   'date':["2020-01-01","2020-01-01","2020-01-01","2020-01-01","2020-01-01","2020-01-01","2020-01-02","2020-01-01","2020-01-02","2020-01-01"],
                   'contribution': [5,5,10,20,30,1,5,5,10,100],
                   'payment-type': ["cash","transfer","cash","transfer","cash","transfer","cash","transfer","cash","transfer",]})
df['date'] = pd.to_datetime(df['date'])

def myfunction(input):
    output = input["name"].value_counts()
    output.index.set_names(['name_x'], inplace=True)
    return output

daily_count = df.groupby(pd.Grouper(key='date', freq='1D')).apply(myfunction)

print(daily_count.reset_index())
 

вывод:

         date    name_x  name
0 2020-01-01       bob     3
1 2020-01-01  charlene     2
2 2020-01-01     alice     2
3 2020-01-01      edna     1
4 2020-01-02  charlene     1
5 2020-01-02     alice     1
 

Не мог бы кто-нибудь, пожалуйста, дать мне рекомендации о том, как лучше всего манипулировать индексами и именами столбцов, чтобы получить чистый результат при использовании apply?

  • Я бы хотел value_counts() , чтобы у него было лучшее имя, чем «имя». Есть ли лучший способ справиться с этим? Должен ли я использовать что-то вроде input["name"] или есть лучший способ?
  • output.index.set_names(['name_x'], inplace=True) кажется немного грязным — есть ли лучший, более чистый способ?

та, Эндрю

Ответ №1:

Я думаю, что все можно сделать с agg

df.groupby(pd.Grouper(key='date', freq='1D')).agg({'name': 'value_counts'}).rename(columns={'name': 'count'}).reset_index()

         date      name  count
0 2020-01-01       bob      3
1 2020-01-01     alice      2
2 2020-01-01  charlene      2
3 2020-01-01      edna      1
4 2020-01-02     alice      1
5 2020-01-02  charlene      1
 

Комментарии:

1. Это правильный ответ, но я действительно ищу способ обработки индексов и имен столбцов в apply() — я обновлю свой вопрос.

2. Я бы не стал использовать apply, это медленнее

Ответ №2:

df.groupby(["date", "name"]).count()

Комментарии:

1. Пожалуйста, всегда, когда вы публикуете код, добавляйте объяснение, как это работает, это повышает ценность публикации и помогает новым пользователям понять, что было сделано

Ответ №3:

Вы можете изменить свою функцию на:

 def myfunction(input):
    output = input["name"].value_counts()
    output = output.rename('count').rename_axis('name')
    return output
 

где rename задайте имя для ряда (т. Е. Выходных данных) и rename_axis задайте имя для внутреннего индекса (т. Е. Значений из input["name"].value_counts() ). Тем не менее, вы всегда можете изменить имена столбцов фрейма данных с rename помощью after вашей операции.

Вывод:

         date      name  count
0 2020-01-01       bob      3
1 2020-01-01     alice      2
2 2020-01-01  charlene      2
3 2020-01-01      edna      1
4 2020-01-02     alice      1
5 2020-01-02  charlene      1
 

Другой подход, который также работает:

 df.groupby([pd.Grouper(key='date', freq='1D'), 'name']).size().rename('count').reset_index()