我有一个像这样的json文件:
{
"A": {
"type1": [
2,
26,
288,
...
],
"type2": [
2,
3,
5,
...
],
"type3": [
23,
26,
288,
...
]
},
"B": {
"type1": [
2,
26,
288,
...
],
"type2": [
2,
3,
5,
...
],
"type3": [
23,
26,
288,
...
]
},
...
"K": {
"type1": [
2,
26,
288,
...
],
"type2": [
2,
3,
5,
...
],
"type3": [
23,
26,
288,
...
]
}
}
以下是复制的示例字典(我从A到J有大约20列,但只有3种类型:type1,type2,type3):
pd.DataFrame({'A': {'type1': ['32',
'21',
'43',
'43',
'43',
'43',
'43',
'43'],
'type2': [
0.133333333333333,
0.36666666666666703,
0.1,
0.30000000000000004,
0.16666666666666702,
0.033333333333333,
0.2,
0.066666666666666],
'type3': [
3,
9,
5,
1,
6,
2]},
'B': {'type1': [
'43',
'43',
'43',
'43',
'43'],
'type2': [
0.23333333333333303,
0.266666666666667,
0.30000000000000004,
0.5666666666666671,
0.16666666666666702,
0.266666666666667],
'type3': [
10,
6,
17,
7,
8,
9,
17,
5,
8]},
'C': {'type1': [
'43',
'43',
'43',
'43',
'43',
'43'],
'type2': [
5.23333333333333,
6.1,
5.4,
3.23333333333333,
17.4,
5.56666666666667,
10.4333333333333,
2.1],
'type3': [
183,
162,
97,
522,
167,
313,
63]},
})
我的df最终应该是这样的:
type1 type2 type3
A 32 0.13 3
A 21 0.36 9
A
........
B
........
C
........
J
所以我换了它: 但后来我不确定如何解压缩这些列表。我每次尝试时都会遇到一些循环:
for x in df.index:
for y in df.loc[x]["type1"]:
df.iloc[index] = df.append({"index": x, "type": y}, ignore_index=True)
index += 1
显然不是那种方式。
我想知道是否有更简单的方法,也许是因为我加载了json?
谢谢!
答案 0 :(得分:4)
我在这里使用for循环.apply(pd.Series).stack
是关键
df=df.T
l=[df[x].apply(pd.Series).stack() for x in df.columns]
s=pd.concat(l,1).reset_index(level=1,drop=True)
s.columns=df.columns
s
Out[347]:
type1 type2 type3
A 32 0.133333 3.0
A 21 0.366667 9.0
A 43 0.100000 5.0
A 43 0.300000 1.0
A 43 0.166667 6.0
A 43 0.033333 2.0
A 43 0.200000 NaN
A 43 0.066667 NaN
B 43 0.233333 10.0
B 43 0.266667 6.0
B 43 0.300000 17.0
B 43 0.566667 7.0
B 43 0.166667 8.0
B NaN 0.266667 9.0
B NaN NaN 17.0
B NaN NaN 5.0
B NaN NaN 8.0
C 43 5.233333 183.0
C 43 6.100000 162.0
C 43 5.400000 97.0
C 43 3.233333 522.0
C 43 17.400000 167.0
C 43 5.566667 313.0
C NaN 10.433333 63.0
C NaN 2.100000 NaN
答案 1 :(得分:3)
没有明确的解决方案,因为列表长度不一样。所以首先你要照顾它,也许用零填充:
# assuming 'data' is your dict
for x in data:
max_length = max([len(data[x][y]) for y in data[x]])
for y in data[x]:
data[x][y] += [np.nan] * (max_length - len(data[x][y]))
然后你可以用面板导入并玩弄索引和排序,直到你得到你想要的东西:)
df = pd.Panel.from_dict(data).to_frame(filter_observations=False).stack().unstack(1).swaplevel(0, 1).sort_index()
minor type1 type2 type3
major
A 0 32 0.133333 3
1 21 0.366667 9
2 43 0.1 5
3 43 0.3 1
4 43 0.166667 6
5 43 0.0333333 2
6 43 0.2 NaN
7 43 0.0666667 NaN
B 0 43 0.233333 10
1 43 0.266667 6
2 43 0.3 17
3 43 0.566667 7
4 43 0.166667 8
5 NaN 0.266667 9
6 NaN NaN 17
7 NaN NaN 5
8 NaN NaN 8
C 0 43 5.23333 183
1 43 6.1 162
2 43 5.4 97
3 43 3.23333 522
4 43 17.4 167
5 43 5.56667 313
6 NaN 10.4333 63
7 NaN 2.1 NaN
答案 2 :(得分:2)
Wen和ascripter的令人敬畏的创意答案。 ascripter的答案是最快的,但值得注意的是Panel is deprecated并将在未来版本中删除。请参阅上面的链接以了解替代方案。
以Wen的代码为基础,可以使用values.tolist()而不是apply()来加速:
In[1]
df = pd.DataFrame.from_dict(data).transpose()
def my_test(df):
l = [pd.DataFrame(df[col].values.tolist(), index=df.index).stack() for col in df.columns]
df2 = pd.concat(l, axis=1).reset_index(level=1, drop=True)
df2.columns = df.columns
return df2
def wen_test(df):
l=[df[x].apply(pd.Series).stack() for x in df.columns]
s=pd.concat(l,1).reset_index(level=1,drop=True)
s.columns=df.columns
return s
%timeit my_test(df)
%timeit wen_test(df)
Out[1]
100 loops, best of 3: 13.2 ms per loop
100 loops, best of 3: 15.7 ms per loop