#pandas #dataframe #stack #pivot #multi-index
#pandas #фрейм данных #стек #сводная #многоиндексный
Вопрос:
У меня есть фрейм данных, который выглядит следующим образом:
df1 = pd.DataFrame({'Type' : ['Q','A','A'], 'Fields': ['Q1','Pre','Post'],'ChildA' : [0,3,5],'ChildB' : [0,2,3]})
ChildA ChildB Fields Field_Type
0 0 0 Q1 Q
1 3 2 Pre A
2 5 3 Post A
всего около 200 дочерних элементов и около 50 вопросов. То, к чему я пытаюсь добраться, выглядит примерно так:
Name Question Pre Post
0 ChildA Q1 3 5
1 ChildB Q1 2 3
2 ChildA Q2 1 4
3 ChildB Q2 3 3
но я не уверен, как лучше всего подойти к этому, я пробовал stack
и pivot
, но оба вернутся ValueError: Index contains duplicate entries, cannot reshape
, или когда это сработает, это не в том формате, который мне нужен, или может работать в правильном формате. Ближе всего, что у меня пока есть, — использовать transpose df2 = df1[0:3].T
, который работает нормально, пока я беру 3 строки за раз, но это кажется очень неэффективным, и я знаю, что должен быть лучший способ с использованием pivot или stack / unstack.
Возможно, это потребует некоторой множественной индексации, поэтому меня привлекает, stack
поскольку pivot
возникают всевозможные проблемы, такие как Exception: Data must be 1-dimensional
когда я попытался бы сказать
df1.pivot(columns='Name',values=['Ben','Jack'])
Любая помощь приветствуется!
Ответ №1:
На самом деле у вас есть два набора данных в одном фрейме данных. Кроме того, в ответах не указано, для какого вопроса они предназначены
- поставьте вопрос против каждого ответа, используя комбинацию
np.where
иfillna()
- только с ответами индексируйте его, поэтому транспонирование имеет смысл
stack()
вопрос снова должен быть столбцом
import numpy as np
df1 = pd.DataFrame({'Type' : ['Q','A','A'], 'Fields': ['Q1','Pre','Post'],'ChildA' : [0,3,5],'ChildB' : [0,2,3]})
maskq = df1["Type"]=="Q"
# need to get question against each answer
df1 = (df1
.assign(Question=lambda x: np.where(x["Type"]=="Q", x["Fields"], np.nan))
.assign(Question=lambda x: x["Question"].fillna(method="ffill"))
)
# now take just questions and organise as required
df1 = df1.loc[~maskq, [c for c in df1.columns if c!="Type"]].set_index(["Fields","Question"]).T.stack()
вывод
Fields Post Pre
Question
ChildA Q1 5 3
ChildB Q1 3 2