我在创建和重新排列数据集时遇到了问题。我查看了 pandas groupby 函数,认为它可能会帮助我做到这一点,但我缺乏经验来实现它。 我在下面创建了一个问题示例: 我的 df:
vehicle color a b c d A1 A2 A3 B1 B2 B3 C1 C2 C3 D1 D2 D3
resp
1 bike green 5 4 1 3 3 4 5 3 5 3 NaN NaN NaN NaN NaN NaN
2 walk red 5 3 3 3 4 5 3 3 5 4 NaN NaN NaN NaN NaN NaN
3 car green 4 2 3 3 4 3 5 4 5 5 NaN NaN NaN NaN NaN NaN
4 car blue 4 5 4 4 NaN NaN NaN NaN NaN NaN 5 5 5 3 3 4
5 bus black 2 4 4 3 NaN NaN NaN 2 3 3 2 2 1 NaN NaN NaN
6 car red 4 2 3 3 3 4 4 NaN NaN NaN 4 4 4 NaN NaN NaN
7 bus blue 5 5 2 3 3 3 5 4 3 2 NaN NaN NaN NaN NaN NaN
8 walk red 3 3 4 3 NaN NaN NaN 5 5 5 5 3 3 NaN NaN NaN
9 car blue 5 3 4 3 3 3 3 NaN NaN NaN 4 3 4 NaN NaN NaN
数据集包含受访者和问题的答案。我想做的是制作一个新的数据框,以 resp 作为索引,并根据受访者的回答方式重新排列数据。 a、b、c、d、车辆和颜色列中的数据在新数据框中为受访者堆叠(希望这是表达它的正确方式)。此外,A 列到 C 列的值位于 BL_val 列下的新框架中。只填大写字母(A1-D3)到小写字母(a,b,c,d)对应的数据,其余为NAN。
我想从中创建一个新的数据框,它应该如下所示:
:
vehicle color sl sl_val BL_val1 BL_val2 BL_val3
resp
1 bike green a 5 3 4 5
1 bike green b 4 3 5 3
1 bike green c 1 NaN NaN NaN
1 bike green d 3 NaN NaN NaN
2 walk red a 5 4 5 3
2 walk red b 3 3 5 4
2 walk red c 3 NaN NaN NaN
2 walk red d 3 NaN NaN NaN
3 car green a 4 4 3 5
3 car green b 2 4 5 5
3 car green c 3 NaN NaN NaN
3 car green d 3 NaN NaN NaN
4 car blue a 4 NaN NaN NaN
4 car blue b 5 NaN NaN NaN
4 car blue c 4 5 5 5
4 car blue d 4 3 3 4
5 bus black a 2 NaN NaN NaN
5 bus black b 4 2 3 3
5 bus black c 4 2 2 1
5 bus black d 3 NaN NaN NaN
6 car red a 4 3 4 4
6 car red b 2 NaN NaN NaN
6 car red c 3 4 4 4
6 car red d 3 NaN NaN NaN
7 bus blue a 5 3 3 5
7 bus blue b 5 4 3 2
7 bus blue c 2 NaN NaN NaN
7 bus blue d 3 NaN NaN NaN
8 walk red a 3 NaN NaN NaN
8 walk red b 3 5 5 5
8 walk red c 4 5 3 3
8 walk red d 3 NaN NaN NaN
9 car blue a 5 3 3 3
9 car blue b 3 NaN NaN NaN
9 car blue c 4 4 3 4
9 car blue d NaN NaN NaN NaN
我真的需要一些帮助,我想不通!!
最佳答案
可能有更简单的方法来做到这一点,但我发现使用 groupby
进行分组,对它们执行显式操作,然后重新组合的模式通常是一种简单的方法得到我想要的。当然,我可以花半个小时想出更优雅的东西,但那样我就没有时间在 SO 上闲逛了。
无论如何,这样的事情怎么样?
df = df.set_index(["resp", "vehicle", "color"])
grouped = df.groupby(lambda x: x[0].lower(), axis=1)
new_grouped = []
for key, group in grouped:
group.columns = ["sl_val"] + ["BL_val{}".format(i) for i in range(1,4)]
group["sl"] = key
new_grouped.append(group)
df2 = pd.concat(new_grouped).reset_index()
df2 = df2.sort(["resp", "vehicle", "color"]).set_index("resp")
df2 = df2[["vehicle", "color", "sl"] + [k for k in df2.columns if "_" in k]]
开始于
>>> df = df.set_index(["resp", "vehicle", "color"])
>>> df
a b c d A1 A2 A3 B1 B2 B3 C1 C2 C3 D1 D2 D3
resp vehicle color
1 bike green 5 4 1 3 3 4 5 3 5 3 NaN NaN NaN NaN NaN NaN
2 walk red 5 3 3 3 4 5 3 3 5 4 NaN NaN NaN NaN NaN NaN
3 car green 4 2 3 3 4 3 5 4 5 5 NaN NaN NaN NaN NaN NaN
4 car blue 4 5 4 4 NaN NaN NaN NaN NaN NaN 5 5 5 3 3 4
5 bus black 2 4 4 3 NaN NaN NaN 2 3 3 2 2 1 NaN NaN NaN
6 car red 4 2 3 3 3 4 4 NaN NaN NaN 4 4 4 NaN NaN NaN
7 bus blue 5 5 2 3 3 3 5 4 3 2 NaN NaN NaN NaN NaN NaN
8 walk red 3 3 4 3 NaN NaN NaN 5 5 5 5 3 3 NaN NaN NaN
9 car blue 5 3 4 3 3 3 3 NaN NaN NaN 4 3 4 NaN NaN NaN
我们可以按小写的首字母分组:
>>> grouped = df.groupby(lambda x: x[0].lower(), axis=1)
生成一堆看起来像这样的组:
>>> next(iter(grouped))
('a', a A1 A2 A3
resp vehicle color
1 bike green 5 3 4 5
2 walk red 5 4 5 3
3 car green 4 4 3 5
4 car blue 4 NaN NaN NaN
5 bus black 2 NaN NaN NaN
6 car red 4 3 4 4
7 bus blue 5 3 3 5
8 walk red 3 NaN NaN NaN
9 car blue 5 3 3 3)
然后我们只需更改名称,添加“sl”
列,然后使用pd.concat
重新组合它们。最后一位与您想要的顺序完全匹配。
最终结果:
>>> df2
vehicle color sl sl_val BL_val1 BL_val2 BL_val3
resp
1 bike green a 5 3 4 5
1 bike green b 4 3 5 3
1 bike green c 1 NaN NaN NaN
1 bike green d 3 NaN NaN NaN
2 walk red a 5 4 5 3
2 walk red b 3 3 5 4
2 walk red c 3 NaN NaN NaN
2 walk red d 3 NaN NaN NaN
3 car green a 4 4 3 5
3 car green b 2 4 5 5
3 car green c 3 NaN NaN NaN
3 car green d 3 NaN NaN NaN
4 car blue a 4 NaN NaN NaN
4 car blue b 5 NaN NaN NaN
4 car blue c 4 5 5 5
4 car blue d 4 3 3 4
5 bus black a 2 NaN NaN NaN
5 bus black b 4 2 3 3
5 bus black c 4 2 2 1
5 bus black d 3 NaN NaN NaN
6 car red a 4 3 4 4
6 car red b 2 NaN NaN NaN
6 car red c 3 4 4 4
6 car red d 3 NaN NaN NaN
7 bus blue a 5 3 3 5
7 bus blue b 5 4 3 2
7 bus blue c 2 NaN NaN NaN
7 bus blue d 3 NaN NaN NaN
8 walk red a 3 NaN NaN NaN
8 walk red b 3 5 5 5
8 walk red c 4 5 3 3
8 walk red d 3 NaN NaN NaN
9 car blue a 5 3 3 3
9 car blue b 3 NaN NaN NaN
9 car blue c 4 4 3 4
9 car blue d 3 NaN NaN NaN
关于python - Pandas stack/groupby 制作一个新的数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18743340/