我有以下系列,并希望将其转换为一个矩阵,其中索引列拆分为单个字母。
我不确定生成矩阵的最简单方法有没有人能帮我解决这个问题?
系列:
A-B 10
A-C 20
A-D 30
B-C 40
B-D 50
C-D 60
期望:
A B C D
A 1 10 20 30
B 10 1 40 50
C 20 40 1 60
D 30 50 60 1
我已使用以下内容将系列的索引拆分为唯一值:
set([item for sublist in [i.split('-') for i in df.index.tolist()] for item in sublist])
示例数据:
df = pd.Series([10,20,30,40,50,60],index=["A-B","A-C","A-D","B-C","B-D","C-D"])
pd.DataFrame([[1,10,20,30],[10,1,40,50],[20,40,1,60],[30,50,60,1]],index = ["A","B", "C", "D"], columns = ["A","B", "C", "D"])
答案 0 :(得分:1)
如果你有
sr = pd.Series([10,20,30,40,50,60],index=["A-B","A-C","A-D","B-C","B-D","C-D"])
您可以重置系列索引以获取 DataFrame 并重命名列
df = sr.reset_index()
df.columns = ['row_col', 'data']
给予
row_col data
0 A-B 10
1 A-C 20
2 A-D 30
3 B-C 40
4 B-D 50
5 C-D 60
现在,完成缺失的组合
df_inv = pd.DataFrame({
'row_col': df.row_col.str[::-1],
'data': df.data
})
df_values = df.append(df_inv)
屈服
row_col data
0 A-B 10
1 A-C 20
2 A-D 30
3 B-C 40
4 B-D 50
5 C-D 60
0 B-A 10
1 C-A 20
2 D-A 30
3 C-B 40
4 D-B 50
5 D-C 60
现在您可以使用 row_col
将 expand
列拆分为两个新列
df_values[['row', 'col']] = df_values.row_col.str.split('-', 1, expand=True)
我们得到
row_col data row col
0 A-B 10 A B
1 A-C 20 A C
2 A-D 30 A D
3 B-C 40 B C
4 B-D 50 B D
5 C-D 60 C D
0 B-A 10 B A
1 C-A 20 C A
2 D-A 30 D A
3 C-B 40 C B
4 D-B 50 D B
5 D-C 60 D C
最后,我们可以pivot
得到“矩阵”(数据透视表)
df_piv = df_values[['row', 'col', 'data']].pivot(
index='row', columns='col'
).fillna(1).astype(int)
我们得到了想要的桌子
data
col A B C D
row
A 1 10 20 30
B 10 1 40 50
C 20 40 1 60
D 30 50 60 1
答案 1 :(得分:0)
在我的解决方案的顶部,我做了两次导入
import pandas as pd
import string
我没有将索引和值放入一个系列中,而是将它们放入列表中
index = ["A-B","A-C","A-D","B-C","B-D","C-D"]
values = [10,20,30,40,50,60]
我们可以初始化两个空数组来存储我们的数字索引。我将字母映射到它们的等价数字,从 0
开始索引,以便我们可以轻松填充矩阵。所以A=0
、B=1
、C=2
等
x = []
y = []
for idx in index:
split = idx.split("-")
x.append(string.ascii_lowercase.index(split[0].lower()))
y.append(string.ascii_lowercase.index(split[1].lower()))
要获得其他组合,我只需将 values
列表加倍,并将 x
和 y
分别附加到 y
和 x
。>
values = [10,20,30,40,50,60] *2
x_copy = x
x = x + y
y = y + x_copy
现在,我创建了我的 final
矩阵,它是 4*4,默认值为 1
。循环遍历 values
列表中的每个值,我通过将值分配给 final
来填充 final[i][j]
矩阵。
final = [[1]*4 for _ in range(4)]
for i in range(len(values)):
final[x[i]][y[i]] = values[i]
现在,我创建一个列/索引名称列表 ['A', 'B', 'C', 'D']
并初始化我的 DataFrame。
names = [chr(ord('@')+1+x) for x in range(4)]
df = pd.DataFrame(final, columns=names, index=names)