两个实验室进行了一系列测量:
test_1
,test_2
,test_3
)两个实验室现在希望将所有数据汇总在一起,并从其组合数据集中得出关于两种仪器的属性的一些结论。首先,他们希望在Seaborn分类图中一起查看所有数据。
适应大熊猫cookbook examples on MultiIndexing的情况这是每个实验室交流数据的方式:
import pandas as pd
import seaborn as sns
from matplotlib import pyplot
df = pd.DataFrame({'test': ['test_1', 'test_2' ,'test_3'],
'foo_110': [1.1, 1.18, 1.19],
'foo_112': [1.15, 1.25, 1.25],
'bar_888': [1.11, 1.15, 1.16],
'bar_657': [1.14, 1.16, 1.18]}
)
df1 = pd.DataFrame({'test': ['test_1', 'test_2' ,'test_3'],
'foo_105': [1.13, 1.17, 1.18],
'foo_112': [1.16, 1.26, 1.28],
'foo_167': [1.18, 1.23, 1.27],
'bar_888': [1.10, 1.14, 1.18],
'bar_415': [1.12, 1.15, 1.16]}
)
为准备其Seaborn图的数据,数据帧将在其索引stacked()
中进行重组,并沿着axis = 0
进行连接:
df = df.set_index('test')
df.columns = pd.MultiIndex.from_tuples([tuple(c.split('_')) for c in df.columns])
df = df.stack().reset_index()
df1 = df1.set_index('test')
df1.columns = pd.MultiIndex.from_tuples([tuple(c.split('_')) for c in df1.columns])
df1 = df1.stack().reset_index()
dfAll = pd.concat((df, df1), axis = 0, sort= False)
dfAll.columns = ['test', 's.no.', 'bar', 'foo']
生产
print(dfAll.head(10))
test s.no. bar foo
0 test_1 110 NaN 1.10
1 test_1 112 NaN 1.15
2 test_1 657 1.14 NaN
3 test_1 888 1.11 NaN
4 test_2 110 NaN 1.18
5 test_2 112 NaN 1.25
6 test_2 657 1.16 NaN
7 test_2 888 1.15 NaN
8 test_3 110 NaN 1.19
9 test_3 112 NaN 1.25
为“ bar”工具绘制所有数据:
sns.set(style="whitegrid")
dfAllplot = sns.catplot(x="test", y ="bar", data=dfAll, hue='s.no.')
这两个实验室现在要做的是保留区分Lab_1
和Lab_2
起源的数据点的能力,以及使用两个实验室提供的其他信息包含误差线的大小,对于test_1
,test_2
和test_3
来说,是不同的。
可以通过在重置索引之后和串联之前向df
和df1
添加一列来轻松提供Lab数据。
df['Lab'] = 'Lab_1'
df1['Lab'] = 'Lab_2'
我没有解决的问题是当为每个stacking()
提供附加信息时如何保存test_x
之后的数据。将df1['urel']
重新排列为Index
后,添加具有相对不确定性的列MultiIndex
:
df1 = df1.set_index('test')
df1.columns = pd.MultiIndex.from_tuples([tuple(c.split('_')) for c in df1.columns])
df1['urel'] = [0.015, 0.014, 0.013]
收益
df1
Out[137]:
foo bar urel
105 112 167 888 415
test
test_1 1.13 1.16 1.18 1.10 1.12 0.015
test_2 1.17 1.26 1.23 1.14 1.15 0.014
test_3 1.18 1.28 1.27 1.18 1.16 0.013
然后
df1 = df1.stack().reset_index()
df1['Lab'] = 'Lab_2'
产生'Lab'
列的所需结果,而不产生'urel'
的所需结果,该结果仅对某些行带有原始值,不能用于进一步的绘图指令。
print(df1.head(10))
test level_1 bar foo urel Lab
0 test_1 105 NaN 1.13 NaN Lab_2
1 test_1 112 NaN 1.16 NaN Lab_2
2 test_1 167 NaN 1.18 NaN Lab_2
3 test_1 415 1.12 NaN NaN Lab_2
4 test_1 888 1.10 NaN NaN Lab_2
5 test_1 NaN NaN 0.015 Lab_2
6 test_2 105 NaN 1.17 NaN Lab_2
7 test_2 112 NaN 1.26 NaN Lab_2
8 test_2 167 NaN 1.23 NaN Lab_2
9 test_2 415 1.15 NaN NaN Lab_2
何时'urel'
应该添加到数据框中?
如果在MultiIndexing之前添加,即从一开始就在这里进行Multi-indexing,堆叠和重置,则'urel'
会再次“中断”。
还是stack()
不是此处提供的示例的正确方法?
答案 0 :(得分:0)
假设包含所有信息的原始数据框为:
df = pd.DataFrame({'test': ['test_1', 'test_2' ,'test_3'],
'foo_110': [1.1, 1.18, 1.19],
'foo_112': [1.15, 1.25, 1.25],
'bar_888': [1.11, 1.15, 1.16],
'bar_657': [1.14, 1.16, 1.18],
'urel' : [0.020, 0.025, 0.018],
'HVL' : [0.156, 0.180, 0.195]}
)
df = df.set_index('test')
其中'urel'
和'HVL'
是两列,它们将遭受前面说明的问题的困扰。将它们带出stacking()
流程,然后返回一个函数,即可完成
def stack_for_seaborn(df, separate=['urel', 'HVL']):
'''
Alternative stacking() of a pandas dataframe for seaborn plotting
First, some columns are extracted from the stacking() process
Second, stacking() is applied
Third, the 'separate' portion of the df is appended considering the new index
'''
idx = df.index
addnl = df[separate]
df.columns = pd.MultiIndex.from_tuples([tuple(c.split('_')) for c in df.columns])
df.drop(separate, axis = 1, level=0, inplace=True)
df = df.stack().reset_index()
df = df.set_index('test')
for t in idx:
for c in addnl.columns:
df.loc[t, c] = addnl[c].loc[t]
return df
df = stack_for_seaborn(df)
df['Lab'] = 'Lab_1'
df.reset_index(inplace=True)
df.columns = ['test', 's.no.', 'bar', 'foo', 'urel', 'HVL', 'Lab']
产生所需的结果,但是熊猫内置方法可能会更好。
print(df.head(10))
test s.no. bar foo urel HVL Lab
0 test_1 110 NaN 1.10 0.020 0.156 Lab_1
1 test_1 112 NaN 1.15 0.020 0.156 Lab_1
2 test_1 657 1.14 NaN 0.020 0.156 Lab_1
3 test_1 888 1.11 NaN 0.020 0.156 Lab_1
4 test_2 110 NaN 1.18 0.025 0.180 Lab_1
5 test_2 112 NaN 1.25 0.025 0.180 Lab_1
6 test_2 657 1.16 NaN 0.025 0.180 Lab_1
7 test_2 888 1.15 NaN 0.025 0.180 Lab_1
8 test_3 110 NaN 1.19 0.018 0.195 Lab_1
9 test_3 112 NaN 1.25 0.018 0.195 Lab_1
答案 1 :(得分:0)
此解决方案对melt()
使用DataFrames
方法。
重新定义两个数据框,以便使用melt方法更容易处理列:
import pandas as pd
import seaborn as sns
from matplotlib import pyplot as plt
df_1 = pd.DataFrame({'urel' : [0.020, 0.025, 0.018],
'HVL' : [0.156, 0.180, 0.195],
'test': ['test_1', 'test_2' ,'test_3'],
'Lab' : ['Lab_1', 'Lab_1', 'Lab_1'],
'foo_110': [1.1, 1.18, 1.19],
'foo_112': [1.15, 1.25, 1.25],
'bar_657': [1.14, 1.16, 1.18],
'bar_888': [1.11, 1.15, 1.16],
}
)
df_2 = pd.DataFrame({'urel' : [0.020, 0.025, 0.018],
'HVL' : [0.156, 0.180, 0.195],
'test': ['test_1', 'test_2' ,'test_3'],
'Lab' : ['Lab_2', 'Lab_2', 'Lab_2'],
'foo_105': [1.13, 1.17, 1.18],
'foo_112': [1.16, 1.26, 1.28],
'foo_167': [1.18, 1.23, 1.27],
'bar_888': [1.10, 1.14, 1.18],
'bar_415': [1.12, 1.15, 1.16],
}
)
for df in (df_1, df_2):
df.columns = pd.MultiIndex.from_tuples([tuple(c.split('_')) for c in df.columns])
df_1 = df_1.melt(id_vars=(df_1.columns.tolist()[:4]),
value_vars=df_1.columns.tolist()[4:],
var_name=['model', 'ser.no']
)
df_2 = df_2.melt(id_vars=(df_2.columns.tolist()[:4]),
value_vars=df_2.columns.tolist()[4:],
var_name=['model', 'ser.no']
)
colnames = ['urel', 'HVL', 'test', 'Lab', 'model', 'ser.no', 'value']
df_1.columns = colnames
df_2.columns = colnames
dfAll = df_1.append(df_2, ignore_index=True)
产生一个DataFrame
,没有不必要的NaN
值,更重要的是,在同一列foo
下的两个工具bar
和model
。
print(dfAll.head(10))
urel HVL test Lab model ser.no value
0 0.020 0.156 test_1 Lab_1 foo 110 1.10
1 0.025 0.180 test_2 Lab_1 foo 110 1.18
2 0.018 0.195 test_3 Lab_1 foo 110 1.19
3 0.020 0.156 test_1 Lab_1 foo 112 1.15
4 0.025 0.180 test_2 Lab_1 foo 112 1.25
5 0.018 0.195 test_3 Lab_1 foo 112 1.25
6 0.020 0.156 test_1 Lab_1 bar 657 1.14
7 0.025 0.180 test_2 Lab_1 bar 657 1.16
8 0.018 0.195 test_3 Lab_1 bar 657 1.18
9 0.020 0.156 test_1 Lab_1 bar 888 1.11
这种更好的结构适用于使用seaborn
的{{1}}图,该图返回一个catplot
对象,每个乐器模型都占据不同的面
FacetGrid