如何根据 pandas 中的字典列创建箱线图
How to create box plots from columns of dicts in pandas
我有一个数据框,其中每一行都是我想在其上使用的字典 seaborn's horizontal box plot。
- x 轴应该是每个
'dialog'
的浮点值
- y 轴应显示 4 种不同的模型
- 每个词性 应该有一个图表,这意味着 'INTJ' 应该有一个图表,'ADV' 应该有另一个图表,依此类推。
我想我必须先做一个 pd.melt
来重组数据,这样新的列就会是 'dialog_num'
、'model_type'
, 和'value'
(做熔化后的自动变量名,但基本上是字典的行)。
之后,也许打破'value'
变量,使每一列都是词性('ADV','INTJ','VERB',等)(这部分对我来说似乎很棘手)。超过这一点...对所有列执行 for 循环并应用水平箱线图?
import pandas as pd
pos =\
{'dialog_num': {0: 0, 1: 1, 2: 2},
'model1': {0: {'ADV': 0.072, 'INTJ': 0.03, 'PRON': 0.133, 'VERB': 0.109},
1: {'ADJ': 0.03, 'NOUN': 0.2, 'PRON': 0.13},
2: {'ADV': 0.083, 'PRON': 0.125, 'VERB': 0.0625}},
'model2': {0: {'ADJ': 0.1428, 'ADV': 0.1428, 'AUX': 0.1428, 'INTJ': 0.285},
1: {'ADJ': 0.1, 'DET': 0.1, 'NOUN': 0.1, 'PROPN': 0.1, 'VERB': 0.2},
2: {'CCONJ': 0.166, 'NOUN': 0.333, 'SPACE': 0.166, 'VERB': 0.3333}},
'model3': {0: {'ADJ': 0.06, 'CCONJ': 0.06, 'NOUN': 0.2, 'PRON': 0.266, 'SPACE': 0.066, 'VERB': 0.333},
1: {'AUX': 0.15, 'PRON': 0.25, 'PUNCT': 0.15, 'VERB': 0.15},
2: {'ADP': 0.125, 'PRON': 0.0625, 'PUNCT': 0.0625, 'VERB': 0.25}},
'model4': {0: {'ADJ': 0.25, 'ADV': 0.08, 'CCONJ': 0.083, 'PRON': 0.166},
1: {'AUX': 0.33, 'PRON': 0.2, 'VERB': 0.0667},
2: {'CCONJ': 0.125, 'NOUN': 0.125, 'PART': 0.125, 'PRON': 0.125, 'SPACE': 0.125, 'VERB': 0.375}}}
df = pd.DataFrame.from_dict(pos)
display(df)
dialog_num model1 model2 model3 model4
0 0 {'INTJ': 0.03, 'ADV': 0.072, 'PRON': 0.133, 'VERB': 0.109} {'INTJ': 0.285, 'AUX': 0.1428, 'ADV': 0.1428, 'ADJ': 0.1428} {'PRON': 0.266, 'VERB': 0.333, 'ADJ': 0.06, 'NOUN': 0.2, 'CCONJ': 0.06, 'SPACE': 0.066} {'PRON': 0.166, 'ADV': 0.08, 'ADJ': 0.25, 'CCONJ': 0.083}
1 1 {'PRON': 0.13, 'ADJ': 0.03, 'NOUN': 0.2} {'PROPN': 0.1, 'VERB': 0.2, 'DET': 0.1, 'ADJ': 0.1, 'NOUN': 0.1} {'PRON': 0.25, 'AUX': 0.15, 'VERB': 0.15, 'PUNCT': 0.15} {'PRON': 0.2, 'AUX': 0.33, 'VERB': 0.0667}
2 2 {'PRON': 0.125, 'ADV': 0.083, 'VERB': 0.0625} {'VERB': 0.3333, 'CCONJ': 0.166, 'NOUN': 0.333, 'SPACE': 0.166} {'PRON': 0.0625, 'VERB': 0.25, 'PUNCT': 0.0625, 'ADP': 0.125} {'PRON': 0.125, 'VERB': 0.375, 'PART': 0.125, 'CCONJ': 0.125, 'NOUN': 0.125, 'SPACE': 0.125}
sns.boxplot
期望在指定 x=
和 y=
. 时以长格式提供 data
- 在这种情况下,根据将每个语音类型作为单独的图的规范,将使用
sns.catplot
,因为有一个col=
参数,可用于创建单独的图对于语音类型。
- 如 OP 中所述,使用
.melt
取消旋转宽数据帧。
.json_normalize
可用于将 'value'
列(dict
类型)转换为平面 table。
- 如果此步骤有问题,请参阅 Split / Explode a column of dictionaries into separate columns with pandas。
- 将扁平化的 table (
vals
) 与 .join
合并到 dfm
。
- 这是可行的,因为
vals
和 dfm
具有匹配的索引。
.melt
数据帧。
- 根据长格式数据框绘制箱线图。
- 在
python 3.10
、pandas 1.4.2
、matplotlib 3.5.1
、seaborn 0.11.2
中测试
import pandas as pd
import seaborn as sns
# load the dict into a dataframe
df = pd.DataFrame(pos)
# unpivot the dataframe
dfm = df.melt(id_vars='dialog_num', var_name='model')
# convert the 'value' column of dicts to a flat table
vals = pd.json_normalize(dfm['value'])
# combine vals to dfm, without the 'value' column
dfm = dfm.iloc[:, 0:-1].join(vals)
# unpivot the dataframe again
dfm = dfm.melt(id_vars=['dialog_num', 'model'])
将所有语音类型绘制在一起
p = sns.boxplot(data=dfm, x='value', y='model')
分别绘制语音类型
- 大多数语音类型只有一个值,或者没有值。
p = sns.catplot(kind='box', data=dfm, x='value', y='model', col='variable', col_wrap=4, height=4)
每一步的数据帧
1: dfm.head()
dialog_num model value
0 0 model1 {'INTJ': 0.03, 'ADV': 0.072, 'PRON': 0.133, 'VERB': 0.109}
1 1 model1 {'PRON': 0.13, 'ADJ': 0.03, 'NOUN': 0.2}
2 2 model1 {'PRON': 0.125, 'ADV': 0.083, 'VERB': 0.0625}
3 0 model2 {'INTJ': 0.285, 'AUX': 0.1428, 'ADV': 0.1428, 'ADJ': 0.1428}
4 1 model2 {'PROPN': 0.1, 'VERB': 0.2, 'DET': 0.1, 'ADJ': 0.1, 'NOUN': 0.1}
2: vals.head()
INTJ ADV PRON VERB ADJ NOUN AUX PROPN DET CCONJ SPACE PUNCT ADP PART
0 0.030 0.0720 0.133 0.1090 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 NaN NaN 0.130 NaN 0.0300 0.2 NaN NaN NaN NaN NaN NaN NaN NaN
2 NaN 0.0830 0.125 0.0625 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 0.285 0.1428 NaN NaN 0.1428 NaN 0.1428 NaN NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN 0.2000 0.1000 0.1 NaN 0.1 0.1 NaN NaN NaN NaN NaN
3: dfm.head()
dialog_num model INTJ ADV PRON VERB ADJ NOUN AUX PROPN DET CCONJ SPACE PUNCT ADP PART
0 0 model1 0.030 0.0720 0.133 0.1090 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 1 model1 NaN NaN 0.130 NaN 0.0300 0.2 NaN NaN NaN NaN NaN NaN NaN NaN
2 2 model1 NaN 0.0830 0.125 0.0625 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 0 model2 0.285 0.1428 NaN NaN 0.1428 NaN 0.1428 NaN NaN NaN NaN NaN NaN NaN
4 1 model2 NaN NaN NaN 0.2000 0.1000 0.1 NaN 0.1 0.1 NaN NaN NaN NaN NaN
4: dfm.head()
dialog_num model variable value
0 0 model1 INTJ 0.030
1 1 model1 INTJ NaN
2 2 model1 INTJ NaN
3 0 model2 INTJ 0.285
4 1 model2 INTJ NaN
我有一个数据框,其中每一行都是我想在其上使用的字典 seaborn's horizontal box plot。
- x 轴应该是每个
'dialog'
的浮点值
- y 轴应显示 4 种不同的模型
- 每个词性 应该有一个图表,这意味着 'INTJ' 应该有一个图表,'ADV' 应该有另一个图表,依此类推。
- x 轴应该是每个
我想我必须先做一个
pd.melt
来重组数据,这样新的列就会是'dialog_num'
、'model_type'
, 和'value'
(做熔化后的自动变量名,但基本上是字典的行)。之后,也许打破
'value'
变量,使每一列都是词性('ADV','INTJ','VERB',等)(这部分对我来说似乎很棘手)。超过这一点...对所有列执行 for 循环并应用水平箱线图?
import pandas as pd
pos =\
{'dialog_num': {0: 0, 1: 1, 2: 2},
'model1': {0: {'ADV': 0.072, 'INTJ': 0.03, 'PRON': 0.133, 'VERB': 0.109},
1: {'ADJ': 0.03, 'NOUN': 0.2, 'PRON': 0.13},
2: {'ADV': 0.083, 'PRON': 0.125, 'VERB': 0.0625}},
'model2': {0: {'ADJ': 0.1428, 'ADV': 0.1428, 'AUX': 0.1428, 'INTJ': 0.285},
1: {'ADJ': 0.1, 'DET': 0.1, 'NOUN': 0.1, 'PROPN': 0.1, 'VERB': 0.2},
2: {'CCONJ': 0.166, 'NOUN': 0.333, 'SPACE': 0.166, 'VERB': 0.3333}},
'model3': {0: {'ADJ': 0.06, 'CCONJ': 0.06, 'NOUN': 0.2, 'PRON': 0.266, 'SPACE': 0.066, 'VERB': 0.333},
1: {'AUX': 0.15, 'PRON': 0.25, 'PUNCT': 0.15, 'VERB': 0.15},
2: {'ADP': 0.125, 'PRON': 0.0625, 'PUNCT': 0.0625, 'VERB': 0.25}},
'model4': {0: {'ADJ': 0.25, 'ADV': 0.08, 'CCONJ': 0.083, 'PRON': 0.166},
1: {'AUX': 0.33, 'PRON': 0.2, 'VERB': 0.0667},
2: {'CCONJ': 0.125, 'NOUN': 0.125, 'PART': 0.125, 'PRON': 0.125, 'SPACE': 0.125, 'VERB': 0.375}}}
df = pd.DataFrame.from_dict(pos)
display(df)
dialog_num model1 model2 model3 model4
0 0 {'INTJ': 0.03, 'ADV': 0.072, 'PRON': 0.133, 'VERB': 0.109} {'INTJ': 0.285, 'AUX': 0.1428, 'ADV': 0.1428, 'ADJ': 0.1428} {'PRON': 0.266, 'VERB': 0.333, 'ADJ': 0.06, 'NOUN': 0.2, 'CCONJ': 0.06, 'SPACE': 0.066} {'PRON': 0.166, 'ADV': 0.08, 'ADJ': 0.25, 'CCONJ': 0.083}
1 1 {'PRON': 0.13, 'ADJ': 0.03, 'NOUN': 0.2} {'PROPN': 0.1, 'VERB': 0.2, 'DET': 0.1, 'ADJ': 0.1, 'NOUN': 0.1} {'PRON': 0.25, 'AUX': 0.15, 'VERB': 0.15, 'PUNCT': 0.15} {'PRON': 0.2, 'AUX': 0.33, 'VERB': 0.0667}
2 2 {'PRON': 0.125, 'ADV': 0.083, 'VERB': 0.0625} {'VERB': 0.3333, 'CCONJ': 0.166, 'NOUN': 0.333, 'SPACE': 0.166} {'PRON': 0.0625, 'VERB': 0.25, 'PUNCT': 0.0625, 'ADP': 0.125} {'PRON': 0.125, 'VERB': 0.375, 'PART': 0.125, 'CCONJ': 0.125, 'NOUN': 0.125, 'SPACE': 0.125}
sns.boxplot
期望在指定x=
和y=
. 时以长格式提供 - 在这种情况下,根据将每个语音类型作为单独的图的规范,将使用
sns.catplot
,因为有一个col=
参数,可用于创建单独的图对于语音类型。
data
- 如 OP 中所述,使用
.melt
取消旋转宽数据帧。 .json_normalize
可用于将'value'
列(dict
类型)转换为平面 table。- 如果此步骤有问题,请参阅 Split / Explode a column of dictionaries into separate columns with pandas。
- 将扁平化的 table (
vals
) 与.join
合并到dfm
。- 这是可行的,因为
vals
和dfm
具有匹配的索引。
- 这是可行的,因为
.melt
数据帧。- 根据长格式数据框绘制箱线图。
- 在
python 3.10
、pandas 1.4.2
、matplotlib 3.5.1
、seaborn 0.11.2
中测试
import pandas as pd
import seaborn as sns
# load the dict into a dataframe
df = pd.DataFrame(pos)
# unpivot the dataframe
dfm = df.melt(id_vars='dialog_num', var_name='model')
# convert the 'value' column of dicts to a flat table
vals = pd.json_normalize(dfm['value'])
# combine vals to dfm, without the 'value' column
dfm = dfm.iloc[:, 0:-1].join(vals)
# unpivot the dataframe again
dfm = dfm.melt(id_vars=['dialog_num', 'model'])
将所有语音类型绘制在一起
p = sns.boxplot(data=dfm, x='value', y='model')
分别绘制语音类型
- 大多数语音类型只有一个值,或者没有值。
p = sns.catplot(kind='box', data=dfm, x='value', y='model', col='variable', col_wrap=4, height=4)
每一步的数据帧
1: dfm.head()
dialog_num model value
0 0 model1 {'INTJ': 0.03, 'ADV': 0.072, 'PRON': 0.133, 'VERB': 0.109}
1 1 model1 {'PRON': 0.13, 'ADJ': 0.03, 'NOUN': 0.2}
2 2 model1 {'PRON': 0.125, 'ADV': 0.083, 'VERB': 0.0625}
3 0 model2 {'INTJ': 0.285, 'AUX': 0.1428, 'ADV': 0.1428, 'ADJ': 0.1428}
4 1 model2 {'PROPN': 0.1, 'VERB': 0.2, 'DET': 0.1, 'ADJ': 0.1, 'NOUN': 0.1}
2: vals.head()
INTJ ADV PRON VERB ADJ NOUN AUX PROPN DET CCONJ SPACE PUNCT ADP PART
0 0.030 0.0720 0.133 0.1090 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 NaN NaN 0.130 NaN 0.0300 0.2 NaN NaN NaN NaN NaN NaN NaN NaN
2 NaN 0.0830 0.125 0.0625 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 0.285 0.1428 NaN NaN 0.1428 NaN 0.1428 NaN NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN 0.2000 0.1000 0.1 NaN 0.1 0.1 NaN NaN NaN NaN NaN
3: dfm.head()
dialog_num model INTJ ADV PRON VERB ADJ NOUN AUX PROPN DET CCONJ SPACE PUNCT ADP PART
0 0 model1 0.030 0.0720 0.133 0.1090 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 1 model1 NaN NaN 0.130 NaN 0.0300 0.2 NaN NaN NaN NaN NaN NaN NaN NaN
2 2 model1 NaN 0.0830 0.125 0.0625 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 0 model2 0.285 0.1428 NaN NaN 0.1428 NaN 0.1428 NaN NaN NaN NaN NaN NaN NaN
4 1 model2 NaN NaN NaN 0.2000 0.1000 0.1 NaN 0.1 0.1 NaN NaN NaN NaN NaN
4: dfm.head()
dialog_num model variable value
0 0 model1 INTJ 0.030
1 1 model1 INTJ NaN
2 2 model1 INTJ NaN
3 0 model2 INTJ 0.285
4 1 model2 INTJ NaN