用于 seaborn 热图的二维数组中的 Bin DataFrame
Bin DataFrame in 2D array for seaborn heatmap
我有一个看起来像的数据框。
+-----------+-------+
| A | B |
+-----------+-------+
| 1 | 1 |
| 2 | 2 |
| 5 | 3 |
| 20 | 4 |
| 25 | 3 |
| 123 | 5 |
| 125 | 6 |
+-----------+-------+
我想根据定义的范围与列 B
中值的总和对列 A
进行分箱。然后将其提供给 seaborn 以生成热图。
+---------+------+-------+-------+-------+-------+-------+-------+-------+-------+--------+
| | 0-10 | 11-20 | 21-30 | 31-40 | 41-50 | 51-60 | 61-70 | 71-80 | 81-90 | 91-100 |
+---------+------+-------+-------+-------+-------+-------+-------+-------+-------+--------+
| 0-100 | 6 | 4 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 101-200 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 201-300 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 301-400 | 0 | 0 | 11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 401-500 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+---------+------+-------+-------+-------+-------+-------+-------+-------+-------+--------+
一种解决方法是循环遍历数据并生成数组。如果有的话,我正在寻找pandas方式。
我尝试使用 seaborn.heatmap 解决问题,如下所示:
df.groupby([pd.cut(df.A, bins=[x for x in range(0,1001,100)], include_lowest=True, right=False),
pd.cut(df.A, bins=[x for x in range(0,101,10)], include_lowest=True, right=False)])
.B.sum().unstack()
但这仅是按前 0-100
B
值分组的。忽略剩余的。
在您的解决方案中,range(0,101,10)
使用最大 range
,例如 101
,因此 A
列中的不匹配值大于 100
- 输出是NaN
s,所以合计后得到0
.
编辑:
#create helper column with integer and modulo division
df['A1'] = df.A % 100
bins1= range(0,df.A.max() // 100 * 100 + 101, 100)
bins2= range(0,df.A1.max() // 10 * 10 + 11, 10)
labels1 = [f'{i}-{j}' if i == 0 else f'{i + 1}-{j}' for i, j in zip(bins1[:-1], bins1[1:])]
labels2 = [f'{i}-{j}' if i == 0 else f'{i + 1}-{j}' for i, j in zip(bins2[:-1], bins2[1:])]
df['a'] = pd.cut(df.A, bins=bins1,labels=labels1, include_lowest=True, right=True)
df['b'] = pd.cut(df.A1, bins=bins2,labels=labels2, include_lowest=True, right=True)
print (df)
A B A1 a b
0 1 1 1 0-100 0-10
1 2 2 2 0-100 0-10
2 5 3 5 0-100 0-10
3 20 4 20 0-100 11-20
4 25 3 25 0-100 21-30
5 123 5 23 101-200 21-30
6 125 6 25 101-200 21-30
df1 = df.pivot_table(index='a', columns='b', values='B', aggfunc='sum')
print (df1)
b 0-10 11-20 21-30
a
0-100 6 4 3
101-200 0 0 11
我有一个看起来像的数据框。
+-----------+-------+
| A | B |
+-----------+-------+
| 1 | 1 |
| 2 | 2 |
| 5 | 3 |
| 20 | 4 |
| 25 | 3 |
| 123 | 5 |
| 125 | 6 |
+-----------+-------+
我想根据定义的范围与列 B
中值的总和对列 A
进行分箱。然后将其提供给 seaborn 以生成热图。
+---------+------+-------+-------+-------+-------+-------+-------+-------+-------+--------+
| | 0-10 | 11-20 | 21-30 | 31-40 | 41-50 | 51-60 | 61-70 | 71-80 | 81-90 | 91-100 |
+---------+------+-------+-------+-------+-------+-------+-------+-------+-------+--------+
| 0-100 | 6 | 4 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 101-200 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 201-300 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 301-400 | 0 | 0 | 11 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 401-500 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
+---------+------+-------+-------+-------+-------+-------+-------+-------+-------+--------+
一种解决方法是循环遍历数据并生成数组。如果有的话,我正在寻找pandas方式。
我尝试使用 seaborn.heatmap 解决问题,如下所示:
df.groupby([pd.cut(df.A, bins=[x for x in range(0,1001,100)], include_lowest=True, right=False),
pd.cut(df.A, bins=[x for x in range(0,101,10)], include_lowest=True, right=False)])
.B.sum().unstack()
但这仅是按前 0-100
B
值分组的。忽略剩余的。
在您的解决方案中,range(0,101,10)
使用最大 range
,例如 101
,因此 A
列中的不匹配值大于 100
- 输出是NaN
s,所以合计后得到0
.
编辑:
#create helper column with integer and modulo division
df['A1'] = df.A % 100
bins1= range(0,df.A.max() // 100 * 100 + 101, 100)
bins2= range(0,df.A1.max() // 10 * 10 + 11, 10)
labels1 = [f'{i}-{j}' if i == 0 else f'{i + 1}-{j}' for i, j in zip(bins1[:-1], bins1[1:])]
labels2 = [f'{i}-{j}' if i == 0 else f'{i + 1}-{j}' for i, j in zip(bins2[:-1], bins2[1:])]
df['a'] = pd.cut(df.A, bins=bins1,labels=labels1, include_lowest=True, right=True)
df['b'] = pd.cut(df.A1, bins=bins2,labels=labels2, include_lowest=True, right=True)
print (df)
A B A1 a b
0 1 1 1 0-100 0-10
1 2 2 2 0-100 0-10
2 5 3 5 0-100 0-10
3 20 4 20 0-100 11-20
4 25 3 25 0-100 21-30
5 123 5 23 101-200 21-30
6 125 6 25 101-200 21-30
df1 = df.pivot_table(index='a', columns='b', values='B', aggfunc='sum')
print (df1)
b 0-10 11-20 21-30
a
0-100 6 4 3
101-200 0 0 11