我遇到创建和重新排列数据集的问题。我看着熊猫群体的功能,并认为它可以帮助我做到这一点,但我没有经验可以实现它。 我在下面创建了一个问题示例: 我的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。
我想从这里创建一个新的数据框架,它看起来像:
DS:
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
我真的需要一些帮助,我无法弄明白!!
答案 0 :(得分:3)
可能有一种更为宽松的方式,但我发现使用groupby
制作组,对它们执行显式操作,然后重新组合的模式通常是一种简单的方法来获取我想要。当然,我可以花半个小时想出更优雅的东西,但那时我就没有时间闲逛了......
无论如何,这样的事情怎么样?
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
答案 1 :(得分:3)
一种天真的方式是写一个辅助函数来提取相关的subDataFrames:
In [11]: def get_letter(df, letter):
res = df.loc[:, ['vehicle', 'color', letter] + [letter.upper() + str(i) for i in xrange(1, 4)]]
res.columns = ['vehicle', 'color', 'sl_val', 'BL_val1', 'BL_val2', 'BL_val3']
res['sl'] = letter
return res
In [12]: get_letter(df, 'a')
Out[12]:
vehicle color sl_val BL_val1 BL_val2 BL_val3 sl
resp
1 bike green 5 3 4 5 a
2 walk red 5 4 5 3 a
3 car green 4 4 3 5 a
4 car blue 4 NaN NaN NaN a
5 bus black 2 NaN NaN NaN a
6 car red 4 3 4 4 a
7 bus blue 5 3 3 5 a
8 walk red 3 NaN NaN NaN a
9 car blue 5 3 3 3 a
然后将这些结果得到你得到的结果(可能有一个排序):
In [13]: pd.concat(get_letter(df, letter) for letter in 'abcd')
In [14]: pd.concat(get_letter(df, letter) for letter in 'abcd').sort()