Pandas поворот на одну строку в каждой подгруппе - PullRequest
1 голос
/ 30 апреля 2020

Учитывая данные, структурированные следующим образом

from io import StringIO
import pandas as pd

data = StringIO("""
person,q,a
1,q1,Yes
1,q2,No
1,q3,Yes
1,q1,No
1,q2,No
1,q3,Yes
2,q1,Yes
2,q2,Yes
2,q3,Yes
3,q1,No
3,q2,Yes
3,q3,Yes
3,q1,Yes
3,q2,No
3,q3,Yes""")

df = pd.read_csv(data)

Я ищу таблицу со следующим выводом

person  q1  q2  q3
1   Yes No  Yes
1   No  No  Yes
2   Yes Yes Yes
3   No  Yes Yes
3   Yes No  Yes

Я могу достичь sh того, что я хочу, проходя по каждой группе и поворот на каждой группе, затем объединение этих результатов, но, по возможности, хотел бы избежать этого. Любые предложения будут оценены.

gb = df.groupby('person')
dfs = []
for gn, _ in gb.groups.items():
    gdf = gb.get_group(gn).copy()
    gdf['grp'] = gdf.groupby('q').cumcount()
    piv = gdf.pivot(index='grp', columns='q', values='a')
    piv['person'] = gn
    dfs.append(piv)

1 Ответ

1 голос
/ 30 апреля 2020

Это похоже на сводку по двум столбцам:

(df.assign(idx=df.groupby(['person','q']).cumcount())
   .pivot_table(index=['person','idx'],columns='q',values='a', aggfunc='first')
   .reset_index('idx',drop=True)
   .reset_index()
)

или эквивалентно с set_index().unstack():

df.assign(idx=df.groupby(['person','q']).cumcount())
   .set_index(['person','idx','q'])['a']
   .unstack(['q'])
   .reset_index('idx',drop=True)
   .reset_index()
)

Вывод:

q  person   q1   q2   q3
0       1  Yes   No  Yes
1       1   No   No  Yes
2       2  Yes  Yes  Yes
3       3   No  Yes  Yes
4       3  Yes   No  Yes
...