如何在 Python 中可视化直方图中其他列的属性
How to visualise attributes from other columns in a histogram in Python
我有一个包含 3 列的数据框:“C_code”、“F_namn”和“D_namn”,其中包含字符串。我想创建一个直方图来显示“F_namn”(地理区域)的分布,并且在每个 bin 中,可以看到“C_code”的分布,即 a、b 或c, 堆叠在一起。
import pandas as pd
import matplotlib.pyplot as plt
C_code = ['a', 'a', 'b', 'a', 'c', 'a', 'b', 'a']
F_namn = ['sthlm', 'norr', 'syd', 'norr', 'norr', 'sthlm', 'syd', 'norr']
D_namn = ['ff', 'rr', 'ff', 'gg', 'ff', 'rr', 'rr', 'ff']
df_test = pd.DataFrame({'C_code': C_code, 'F_namn': F_namn, 'D_namn': D_namn})
df_counts_test = df_test.apply(pd.value_counts)
df_counts_test['F_namn'].dropna().plot.bar(stacked=True)
plt.show()
这是 F namn 的直方图,我希望每个 bin 都有 3 个“区域”,其中包含来自同一数据帧的“C_code”列的分布。
你的主要问题是计算错误。
如果你使用 print(df_counts_test)
那么你应该看到结果对于你想要的情节是无用的。
使用 pd.value_counts
计算总计数。你的情节只显示你有多少次名字 sthlm
, norr
, syd
在名单上但它不计算你有多少次 a
,b
,c
每 sthlm
, norr
, syd
.
您应该使用 groupby('F_namn')
,并且在每个组中,您应该在 'C_code'
列上使用 value_counts
来分别计算每个组。
首先,我为结果创建 DataFrame
- 我将为每个组添加包含结果的列。
开始时需要 rows/indexes。如果我不定义 index
那么它不会添加结果。
result = pd.DataFrame(index=['a', 'b', 'c'])
接下来我按 F_name
分组并分别计算每个组的 value_counts
for name, data in df_test.groupby('F_namn'):
#print(name)
#print(data['C_code'].value_counts())
result[name] = data['C_code'].value_counts()
这给了我:
norr sthlm syd
a 3.0 2.0 NaN
b NaN NaN 2.0
c 1.0 NaN NaN
我可以用零替换 NaN
但即使使用 NaN
它也应该正确绘制
result = result.fillna(0)
它还需要 transpose
它 - 这意味着将列转换为行。
result = result.T # transpose
这给了我:
a b c
norr 3.0 0.0 1.0
sthlm 2.0 0.0 0.0
syd 0.0 2.0 0.0
终于可以画图了
result.plot.bar(stacked=True)
plt.show()
这给了我
完整的工作代码:
import pandas as pd
import matplotlib.pyplot as plt
C_code = ['a', 'a', 'b', 'a', 'c', 'a', 'b', 'a']
F_namn = ['sthlm', 'norr', 'syd', 'norr', 'norr', 'sthlm', 'syd', 'norr']
D_namn = ['ff', 'rr', 'ff', 'gg', 'ff', 'rr', 'rr', 'ff']
df_test = pd.DataFrame({
'C_code': C_code,
'F_namn': F_namn,
'D_namn': D_namn
})
print(df_test)
result = pd.DataFrame(index=['a', 'b', 'c'])
for name, data in df_test.groupby('F_namn'):
#print(name)
#print(data['C_code'].value_counts())
result[name] = data['C_code'].value_counts()
print(result)
result = result.fillna(0) # put `zero`
result = result.T # transpose
print(result)
result.plot.bar(stacked=True)
plt.show()
我有一个包含 3 列的数据框:“C_code”、“F_namn”和“D_namn”,其中包含字符串。我想创建一个直方图来显示“F_namn”(地理区域)的分布,并且在每个 bin 中,可以看到“C_code”的分布,即 a、b 或c, 堆叠在一起。
import pandas as pd
import matplotlib.pyplot as plt
C_code = ['a', 'a', 'b', 'a', 'c', 'a', 'b', 'a']
F_namn = ['sthlm', 'norr', 'syd', 'norr', 'norr', 'sthlm', 'syd', 'norr']
D_namn = ['ff', 'rr', 'ff', 'gg', 'ff', 'rr', 'rr', 'ff']
df_test = pd.DataFrame({'C_code': C_code, 'F_namn': F_namn, 'D_namn': D_namn})
df_counts_test = df_test.apply(pd.value_counts)
df_counts_test['F_namn'].dropna().plot.bar(stacked=True)
plt.show()
这是 F namn 的直方图,我希望每个 bin 都有 3 个“区域”,其中包含来自同一数据帧的“C_code”列的分布。
你的主要问题是计算错误。
如果你使用 print(df_counts_test)
那么你应该看到结果对于你想要的情节是无用的。
使用 pd.value_counts
计算总计数。你的情节只显示你有多少次名字 sthlm
, norr
, syd
在名单上但它不计算你有多少次 a
,b
,c
每 sthlm
, norr
, syd
.
您应该使用 groupby('F_namn')
,并且在每个组中,您应该在 'C_code'
列上使用 value_counts
来分别计算每个组。
首先,我为结果创建 DataFrame
- 我将为每个组添加包含结果的列。
开始时需要 rows/indexes。如果我不定义 index
那么它不会添加结果。
result = pd.DataFrame(index=['a', 'b', 'c'])
接下来我按 F_name
分组并分别计算每个组的 value_counts
for name, data in df_test.groupby('F_namn'):
#print(name)
#print(data['C_code'].value_counts())
result[name] = data['C_code'].value_counts()
这给了我:
norr sthlm syd
a 3.0 2.0 NaN
b NaN NaN 2.0
c 1.0 NaN NaN
我可以用零替换 NaN
但即使使用 NaN
result = result.fillna(0)
它还需要 transpose
它 - 这意味着将列转换为行。
result = result.T # transpose
这给了我:
a b c
norr 3.0 0.0 1.0
sthlm 2.0 0.0 0.0
syd 0.0 2.0 0.0
终于可以画图了
result.plot.bar(stacked=True)
plt.show()
这给了我
完整的工作代码:
import pandas as pd
import matplotlib.pyplot as plt
C_code = ['a', 'a', 'b', 'a', 'c', 'a', 'b', 'a']
F_namn = ['sthlm', 'norr', 'syd', 'norr', 'norr', 'sthlm', 'syd', 'norr']
D_namn = ['ff', 'rr', 'ff', 'gg', 'ff', 'rr', 'rr', 'ff']
df_test = pd.DataFrame({
'C_code': C_code,
'F_namn': F_namn,
'D_namn': D_namn
})
print(df_test)
result = pd.DataFrame(index=['a', 'b', 'c'])
for name, data in df_test.groupby('F_namn'):
#print(name)
#print(data['C_code'].value_counts())
result[name] = data['C_code'].value_counts()
print(result)
result = result.fillna(0) # put `zero`
result = result.T # transpose
print(result)
result.plot.bar(stacked=True)
plt.show()