amr*_*tha 8 python dictionary dataframe python-3.x pandas
我dict喜欢这样的:
data = {'1':{'a':10, 'b':30}, '2':{'a':20, 'b':60}}
Run Code Online (Sandbox Code Playgroud)
我想转换成这样的数据帧:
x y z
1 a 10
1 b 30
2 a 20
2 b 60
Run Code Online (Sandbox Code Playgroud)
有人知道吗?
jez*_*ael 12
使用dictionary comprehension有concat:
df = pd.concat({k: pd.Series(v) for k, v in data.items()}).reset_index()
df.columns = list('xyz')
print (df)
x y z
0 1 a 10
1 1 b 30
2 2 a 20
3 2 b 60
Run Code Online (Sandbox Code Playgroud)
为了获得更好的性能,请使用list compehension带有排序:
L = sorted([(k,k1,v1) for k,v in data.items() for k1,v1 in v.items()],
key=lambda x: (x[0], x[1]))
print (L)
[('1', 'a', 10), ('1', 'b', 30), ('2', 'a', 20), ('2', 'b', 60)]
df = pd.DataFrame(L, columns=list('xyz'))
print (df)
x y z
0 1 a 10
1 1 b 30
2 2 a 20
3 2 b 60
Run Code Online (Sandbox Code Playgroud)
时间:
In [34]: %timeit jez1(data)
16.8 ms ± 403 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [35]: %timeit jez(data)
1.96 s ± 90.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [37]: %timeit jp(data)
43 ms ± 353 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
Run Code Online (Sandbox Code Playgroud)
与@jp相同的代码:
data = {str(k): {'a': 10, 'b': 30} for k in range(10000)}
def jp(data):
return pd.melt(pd.DataFrame.from_dict(data, orient='index').reset_index().rename(columns={'index': 'x'}),
id_vars=['x'], value_vars=['a', 'b'], var_name='y', value_name='z')\
.sort_values(['x', 'y']).reset_index(drop=True)
def jez(data):
df = pd.concat({k: pd.Series(v) for k, v in data.items()}).reset_index()
df.columns = list('xyz')
return df
def jez1(data):
L = sorted([(k,k1,v1) for k,v in data.items() for k1,v1 in v.items()], key=lambda x: (x[0], x[1]))
df = pd.DataFrame(L, columns=list('xyz'))
return df
assert (jez1(data).values == jez(data).values).all()
Run Code Online (Sandbox Code Playgroud)
这是使用的一种方式pandas.melt.
d = {'1':{'a':10, 'b':30}, '2':{'a':20, 'b':60}}
res = pd.melt(pd.DataFrame.from_dict(d, orient='index'),
value_vars=['a', 'b'], var_name='y', value_name='z')
print(res)
# y z
# 0 a 10
# 1 a 20
# 2 b 30
# 3 b 60
Run Code Online (Sandbox Code Playgroud)
绩效基准
我预计pandas.melt效率低下,但申请pandas.concat大量字典可能会更加昂贵.
data = {str(k): {'a': 10, 'b': 30} for k in range(10000)}
def jp(data):
return pd.melt(pd.DataFrame.from_dict(data, orient='index').reset_index().rename(columns={'index': 'x'}),
id_vars=['x'], value_vars=['a', 'b'], var_name='y', value_name='z')\
.sort_values(['x', 'y']).reset_index(drop=True)
def jez(data):
df = pd.concat({k: pd.Series(v) for k, v in data.items()}).reset_index()
df.columns = list('xyz')
return df
assert (jp(data).values == jez(data).values).all()
%timeit jp(data) # 51.8 ms per loop
%timeit jez(data) # 2.62 s per loop
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2424 次 |
| 最近记录: |