你会如何翻转和折叠矩阵 pandas 的对角线?
How would you flip and fold diagonaly a matrix with pandas?
我有一些数据想组织起来用于可视化和统计,但我不知道如何进行。
数据位于 3 列(stimA、stimB 和 subjectAnswer)和 10 行(成对的数字)中,它们来自成对比较测试,采用 panda 的数据帧格式。示例:
stimA
stimB
subjectAnswer
1
2
36
3
1
55
5
3
98
...
...
...
我的目标是将它们组织成一个矩阵,每行和每列对应一个刺激,subjectAnswer 数据分组到矩阵对角线的左侧(在我的示例中,subjectAnswer 36 对应于 stimA 1 和stimB 2 应该转到索引 [2][1]),像这样:
stimA/stimB
1
2
3
4
5
1
...
2
36
3
55
4
...
5
...
...
98
我成功地将第一个 table 旋转到矩阵,但我无法在数据诊断的左侧成功排列,这是我的代码:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
session1 = pd.read_csv(filepath, names=['stimA', 'stimB', 'subjectAnswer'])
pivoted = session1.pivot('stimA','stimB','subjectAnswer')
给出:
会话 1 :
stimA stimB subjectAnswer
0 1 3 6
1 4 3 21
2 4 5 26
3 2 3 10
4 1 2 6
5 1 5 6
6 4 1 6
7 5 2 13
8 3 5 15
9 2 4 26
旋转:
stimB 1 2 3 4 5
stimA
1 NaN 6.0 6.0 NaN 6.0
2 NaN NaN 10.0 26.0 NaN
3 NaN NaN NaN NaN 15.0
4 6.0 NaN 21.0 NaN 26.0
5 NaN 13.0 NaN NaN NaN
透视的预期输出:
stimB 1 2 3 4 5
stimA
1 NaN NaN Nan NaN NaN
2 6.0 NaN Nan NaN NaN
3 6.0 10.0 NaN NaN NaN
4 6.0 26.0 21.0 NaN NaN
5 6.0 13.0 15.0 26.0 NaN
非常感谢您的帮助!
如果我没理解错的话,刺激 A 和 B 是可以互换的。所以为了得到你想要的矩阵布局,你可以在那些A小于B的行中将A与B交换。换句话说,你不用原来的A和B作为枢轴table,而是A和B的最大值和最小值:
session1['stim_min'] = np.min(session1[['stimA', 'stimB']], axis=1)
session1['stim_max'] = np.max(session1[['stimA', 'stimB']], axis=1)
pivoted = session1.pivot('stim_max', 'stim_min', 'subjectAnswer')
pivoted
stim_min 1 2 3 4
stim_max
2 6.0 NaN NaN NaN
3 6.0 10.0 NaN NaN
4 6.0 26.0 21.0 NaN
5 6.0 13.0 15.0 26.0
sort
沿列轴的列 stimA
和 stimB
并在数据框中分配两个临时列,即 x
和 y
。这里需要排序,因为我们需要保证得到的矩阵裁剪在右上角。
使用索引 y
、列 x
和值 subjectanswer
对数据框进行透视,然后重新索引重塑的框架以确保所有可用的唯一 stim
名称出现在矩阵的索引和列中
session1[['x', 'y']] = np.sort(session1[['stimA', 'stimB']], axis=1)
i = np.union1d(session1['x'], session1['y'])
session1.pivot('y', 'x','subjectAnswer').reindex(i, i)
x 1 2 3 4 5
y
1 NaN NaN NaN NaN NaN
2 6.0 NaN NaN NaN NaN
3 6.0 10.0 NaN NaN NaN
4 6.0 26.0 21.0 NaN NaN
5 6.0 13.0 15.0 26.0 NaN
我有一些数据想组织起来用于可视化和统计,但我不知道如何进行。
数据位于 3 列(stimA、stimB 和 subjectAnswer)和 10 行(成对的数字)中,它们来自成对比较测试,采用 panda 的数据帧格式。示例:
stimA | stimB | subjectAnswer |
---|---|---|
1 | 2 | 36 |
3 | 1 | 55 |
5 | 3 | 98 |
... | ... | ... |
我的目标是将它们组织成一个矩阵,每行和每列对应一个刺激,subjectAnswer 数据分组到矩阵对角线的左侧(在我的示例中,subjectAnswer 36 对应于 stimA 1 和stimB 2 应该转到索引 [2][1]),像这样:
stimA/stimB | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
1 | ... | ||||
2 | 36 | ||||
3 | 55 | ||||
4 | ... | ||||
5 | ... | ... | 98 |
我成功地将第一个 table 旋转到矩阵,但我无法在数据诊断的左侧成功排列,这是我的代码:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
session1 = pd.read_csv(filepath, names=['stimA', 'stimB', 'subjectAnswer'])
pivoted = session1.pivot('stimA','stimB','subjectAnswer')
给出:
会话 1 :
stimA stimB subjectAnswer
0 1 3 6
1 4 3 21
2 4 5 26
3 2 3 10
4 1 2 6
5 1 5 6
6 4 1 6
7 5 2 13
8 3 5 15
9 2 4 26
旋转:
stimB 1 2 3 4 5
stimA
1 NaN 6.0 6.0 NaN 6.0
2 NaN NaN 10.0 26.0 NaN
3 NaN NaN NaN NaN 15.0
4 6.0 NaN 21.0 NaN 26.0
5 NaN 13.0 NaN NaN NaN
透视的预期输出:
stimB 1 2 3 4 5
stimA
1 NaN NaN Nan NaN NaN
2 6.0 NaN Nan NaN NaN
3 6.0 10.0 NaN NaN NaN
4 6.0 26.0 21.0 NaN NaN
5 6.0 13.0 15.0 26.0 NaN
非常感谢您的帮助!
如果我没理解错的话,刺激 A 和 B 是可以互换的。所以为了得到你想要的矩阵布局,你可以在那些A小于B的行中将A与B交换。换句话说,你不用原来的A和B作为枢轴table,而是A和B的最大值和最小值:
session1['stim_min'] = np.min(session1[['stimA', 'stimB']], axis=1)
session1['stim_max'] = np.max(session1[['stimA', 'stimB']], axis=1)
pivoted = session1.pivot('stim_max', 'stim_min', 'subjectAnswer')
pivoted
stim_min 1 2 3 4
stim_max
2 6.0 NaN NaN NaN
3 6.0 10.0 NaN NaN
4 6.0 26.0 21.0 NaN
5 6.0 13.0 15.0 26.0
sort
沿列轴的列 stimA
和 stimB
并在数据框中分配两个临时列,即 x
和 y
。这里需要排序,因为我们需要保证得到的矩阵裁剪在右上角。
使用索引 y
、列 x
和值 subjectanswer
对数据框进行透视,然后重新索引重塑的框架以确保所有可用的唯一 stim
名称出现在矩阵的索引和列中
session1[['x', 'y']] = np.sort(session1[['stimA', 'stimB']], axis=1)
i = np.union1d(session1['x'], session1['y'])
session1.pivot('y', 'x','subjectAnswer').reindex(i, i)
x 1 2 3 4 5
y
1 NaN NaN NaN NaN NaN
2 6.0 NaN NaN NaN NaN
3 6.0 10.0 NaN NaN NaN
4 6.0 26.0 21.0 NaN NaN
5 6.0 13.0 15.0 26.0 NaN