[英]Python pandas groupby aggregate on multiple columns, then pivot
[英]Pandas groupby/pivot by date on multiple columns
我正試圖從這個df獲得以下輸出。 它是從一個django查詢構造的,它被轉換為df:
messages = Message.objects.all()
df = pd.DataFrame.from_records(messages.values())
+---+-----------------+------------+---------------------+
| | date_time | error_desc | text |
+---+-----------------+------------+---------------------+
| 0 | 3/31/2019 12:35 | Error msg | Hello there |
| 1 | 3/31/2019 12:35 | | Nothing really here |
| 2 | 4/1/2019 12:35 | Error msg | What if I told you |
| 3 | 4/1/2019 12:35 | | Yes |
| 4 | 4/1/2019 12:35 | Error Msg | Maybe |
| 5 | 4/2/2019 12:35 | | Sure I could |
| 6 | 4/2/2019 12:35 | | Hello again |
+---+-----------------+------------+---------------------+
輸出:
+-----------+-------------+--------+-----------------------------+--------------+
| date | Total count | Errors | Greeting (start with hello) | errors/total |
+-----------+-------------+--------+-----------------------------+--------------+
| 3/31/2019 | 2 | 1 | 1 | 50% |
| 4/1/2019 | 3 | 2 | 0 | 66.67% |
| 4/2/2019 | 2 | 0 | 1 | 0% |
+-----------+-------------+--------+-----------------------------+--------------+
我部分能夠使用以下代碼到達那里,但它似乎有點迂回的做法。 我根據他們是否符合條件然后分組來標記每個'是'/'否'。
df['date'] = df['date_time'].dt.date
df['greeting'] = np.where(df["text"].str.lower().str.startswith('hello'), "Yes", "No")
df['error'] = np.where(df["error_desc"].notnull(), "Yes", "No")
df.set_index("date")
.groupby(level="date")
.apply(lambda g: g.apply(pd.value_counts))
.unstack(level=1)
.fillna(0)
這會產生計數,但會產生多個是/否列。
在這之后我可以做一些操作,但有沒有更有效的方法來提出我之后的輸出?
您可以在多列上使用lambda
:
df.groupby('date').apply(lambda x:
pd.Series({'total_count': len(x),
'error_count': (x['error'] == 'Yes').sum(),
'hello_count': (x['greeting'] == 'Yes').sum()}))
要計算比率:
df['errors/total'] = df['error_count'] / df['total_count']
這是我試過的,給了我你想要的答案:
df['date_time'] = pd.to_datetime(df['date_time']).dt.date
df1=pd.DataFrame()
df1['total count'] = df['date_time'].groupby(df['date_time']).count()
df1['errors'] = df['error_desc'].groupby(df['date_time']).count()
df1['Greeting'] = df['text'].groupby(df['date_time']).apply(lambda x: x[x.str.lower().str.startswith('hello')].count())
df1['errors/total'] = round(df1['errors']/df1['total count']*100,2)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.