Unpivot/Flatten pandas 将 table 转换为一级索引
Unpivot/Flatten pandas pivot table into one level index
为了进行分析,我从一个数据框开始,它看起来像这样(但要大得多):
ID1 ID2 type Number
0 IE345 E90 I 38
1 IE345 E92 E 26
2 IE345 E93 E 21
3 IE345 E95 R 9
4 IE346 E94 I 41
7 IE346 BLK E 1
我想取消透视以下数据框:
Df1 = pd.pivot_table(loads, values=['Number'],
index = ['ID1', 'ID2'],
columns=['Type'], margins=True,
aggfunc=[sum] , fill_value=0)
Df1:
sum
Number
type B D E I L R All
ID1 ID2
IE345 E90 0 0 0 38 0 0 38
E92 0 0 26 0 0 0 26
E93 0 0 21 0 0 0 21
E95 0 0 0 0 0 9 9
IE346 E94 0 0 0 41 0 0 41
BLK 0 0 1 0 0 0 1
进入:
Df1:
ID1 ID2 B D E I L R All
IE345 E90 0 0 0 38 0 0 38
IE345 E92 0 0 26 0 0 0 26
IE345 E93 0 0 21 0 0 0 21
IE345 E95 0 0 0 0 0 9 9
IE346 E94 0 0 0 41 0 0 41
IE346 BLK 0 0 1 0 0 0 1
似乎 pandas.melt 是我要找的东西,但无法让它发挥作用。
然后我想添加一行中最高值的列名,但当然没有边距:
ID1 ID2 B D E I L R All Max
IE345 E90 0 0 0 38 0 0 38 I
IE345 E92 0 0 26 0 0 0 26 E
IE345 E93 0 0 21 0 6 0 27 E
IE345 E95 0 0 0 0 0 9 9 R
IE345 E94 0 0 0 41 0 0 41 I
IE345 BLK 0 0 1 0 1 0 2 E
对于最大值,我使用了:
df['Max'] = df.idxmax(axis=1, skipna=True)
但不幸的是,这需要全部。关于如何以最有效的方式实现我的目标有什么想法吗?
!!!编辑!!!!
对于第一部分,我构建了一个解决方案,该解决方案 returns 确定了一个逆轴 table!看这里的代码:
df.columns = df.columns.get_level_values('Type')
df.reset_index(inplace=True)
现在我尝试了 Vmg 的解决方案,但不幸的是 returns:
ValueError: could not convert string to float:
关于如何解决这个问题有什么想法吗?
您描述的第一个转换似乎没有必要,因为您似乎仍然希望 ID1
和 ID2
成为索引。第一种表示方式 pandas 显示多个索引,而无需为第二个条目中的每个条目重复第一个索引。
你手头的问题,应用 idxmax
没有全部可以通过以下方式实现:
proef['Dominant'] = proef.iloc[:,:-1].idxmax(axis=1, skipna=True)
其中 iloc[:,:-1]
仅表示您忽略了最右边的列。
正如@vmg 已经说过的,idxmax
会成功:
import io
import StringIO # for Python 2.X
import pandas as pd
data = """\
id1 id2 type number
0 IE345 E90 I 38
1 IE345 E92 E 26
2 IE345 E93 E 21
3 IE345 E95 R 9
4 IE346 E94 I 41
7 IE346 BLK E 1
"""
#loads = pd.read_csv(io.StringIO(data), sep='\s+', index_col=0) # for Python 3.X
loads = pd.read_csv(StringIO.StringIO(data), sep='\s+', index_col=0) # for Python 2.X
# **** interesting part starts here ****
# save all unique types, we will use it later
types = loads.type.unique()
df = pd.pivot_table(loads, values=['number'],
index = ['id1', 'id2'],
columns=['type'], margins=True,
aggfunc='sum', fill_value=0) \
.reset_index()
# reset column names
df.columns = [c[1] if c[1] else c[0] for c in df.columns.tolist()]
df['max'] = df[types].idxmax(axis=1)
输出:
In [266]: df
Out[266]:
id1 id2 E I R All max
0 IE345 E90 0.0 38.0 0.0 38.0 I
1 IE345 E92 26.0 0.0 0.0 26.0 E
2 IE345 E93 21.0 0.0 0.0 21.0 E
3 IE345 E95 0.0 0.0 9.0 9.0 R
4 IE346 BLK 1.0 0.0 0.0 1.0 E
5 IE346 E94 0.0 41.0 0.0 41.0 I
6 All 48.0 79.0 9.0 136.0 I
为了进行分析,我从一个数据框开始,它看起来像这样(但要大得多):
ID1 ID2 type Number
0 IE345 E90 I 38
1 IE345 E92 E 26
2 IE345 E93 E 21
3 IE345 E95 R 9
4 IE346 E94 I 41
7 IE346 BLK E 1
我想取消透视以下数据框:
Df1 = pd.pivot_table(loads, values=['Number'], index = ['ID1', 'ID2'], columns=['Type'], margins=True, aggfunc=[sum] , fill_value=0)
Df1:
sum
Number
type B D E I L R All
ID1 ID2
IE345 E90 0 0 0 38 0 0 38
E92 0 0 26 0 0 0 26
E93 0 0 21 0 0 0 21
E95 0 0 0 0 0 9 9
IE346 E94 0 0 0 41 0 0 41
BLK 0 0 1 0 0 0 1
进入:
Df1:
ID1 ID2 B D E I L R All
IE345 E90 0 0 0 38 0 0 38
IE345 E92 0 0 26 0 0 0 26
IE345 E93 0 0 21 0 0 0 21
IE345 E95 0 0 0 0 0 9 9
IE346 E94 0 0 0 41 0 0 41
IE346 BLK 0 0 1 0 0 0 1
似乎 pandas.melt 是我要找的东西,但无法让它发挥作用。
然后我想添加一行中最高值的列名,但当然没有边距:
ID1 ID2 B D E I L R All Max
IE345 E90 0 0 0 38 0 0 38 I
IE345 E92 0 0 26 0 0 0 26 E
IE345 E93 0 0 21 0 6 0 27 E
IE345 E95 0 0 0 0 0 9 9 R
IE345 E94 0 0 0 41 0 0 41 I
IE345 BLK 0 0 1 0 1 0 2 E
对于最大值,我使用了:
df['Max'] = df.idxmax(axis=1, skipna=True)
但不幸的是,这需要全部。关于如何以最有效的方式实现我的目标有什么想法吗?
!!!编辑!!!!
对于第一部分,我构建了一个解决方案,该解决方案 returns 确定了一个逆轴 table!看这里的代码:
df.columns = df.columns.get_level_values('Type')
df.reset_index(inplace=True)
现在我尝试了 Vmg 的解决方案,但不幸的是 returns:
ValueError: could not convert string to float:
关于如何解决这个问题有什么想法吗?
您描述的第一个转换似乎没有必要,因为您似乎仍然希望 ID1
和 ID2
成为索引。第一种表示方式 pandas 显示多个索引,而无需为第二个条目中的每个条目重复第一个索引。
你手头的问题,应用 idxmax
没有全部可以通过以下方式实现:
proef['Dominant'] = proef.iloc[:,:-1].idxmax(axis=1, skipna=True)
其中 iloc[:,:-1]
仅表示您忽略了最右边的列。
正如@vmg 已经说过的,idxmax
会成功:
import io
import StringIO # for Python 2.X
import pandas as pd
data = """\
id1 id2 type number
0 IE345 E90 I 38
1 IE345 E92 E 26
2 IE345 E93 E 21
3 IE345 E95 R 9
4 IE346 E94 I 41
7 IE346 BLK E 1
"""
#loads = pd.read_csv(io.StringIO(data), sep='\s+', index_col=0) # for Python 3.X
loads = pd.read_csv(StringIO.StringIO(data), sep='\s+', index_col=0) # for Python 2.X
# **** interesting part starts here ****
# save all unique types, we will use it later
types = loads.type.unique()
df = pd.pivot_table(loads, values=['number'],
index = ['id1', 'id2'],
columns=['type'], margins=True,
aggfunc='sum', fill_value=0) \
.reset_index()
# reset column names
df.columns = [c[1] if c[1] else c[0] for c in df.columns.tolist()]
df['max'] = df[types].idxmax(axis=1)
输出:
In [266]: df
Out[266]:
id1 id2 E I R All max
0 IE345 E90 0.0 38.0 0.0 38.0 I
1 IE345 E92 26.0 0.0 0.0 26.0 E
2 IE345 E93 21.0 0.0 0.0 21.0 E
3 IE345 E95 0.0 0.0 9.0 9.0 R
4 IE346 BLK 1.0 0.0 0.0 1.0 E
5 IE346 E94 0.0 41.0 0.0 41.0 I
6 All 48.0 79.0 9.0 136.0 I