Pandas:从邻接矩阵到一系列节点列表
Pandas: from adjacency matrix to series of node lists
我有,我认为这是一个非常普遍的问题。即,在节点列表的列表中重铸二分邻接矩阵。在 Pandas 中,这意味着从特定的 pd.DataFrame
格式转换为特定的 pd.Series
格式。
对于非离散数学人员,这看起来像以下转换:
来自
df = pd.DataFrame(columns=['item1','item2','item3'],
index=['foo','bar','qux'],
data = [[1,1,0],[0,1,1],[0,0,0]])
看起来像
item1 item2 item3
foo 1 1 0
bar 0 1 1
qux 0 0 0
到
srs = pd.Series([['item1','item2'],['item2','item3'],[]],index=['foo','bar','qux'])
看起来像
foo [item1, item2]
bar [item2, item3]
qux []
dtype: object
我已经通过以下代码部分实现了这个目标:
df_1 = df.stack().reset_index()
srs = df_1.loc[df_1[0]==1].groupby('level_0')['level_1'].apply(list)
除了有点不可读之外,还存在一路上掉落的问题 qux
。
是否有到达所需结果的更短路径?
如果想避免通过 stack
和 groupby
进行重塑,可以使用列表理解将 0,1
转换为 DataFrame.astype
的布尔值,然后过滤列名称,最后一次它到 Series
构造函数:
print([list(df.columns[x]) for x in df.astype(bool).to_numpy()])
[['item1', 'item2'], ['item2', 'item3'], []]
s = pd.Series([list(df.columns[x]) for x in df.astype(bool).to_numpy()], index=df.index)
print(s)
foo [item1, item2]
bar [item2, item3]
qux []
dtype: object
如果性能也很重要,请使用:
c = df.columns.to_numpy()
s = pd.Series([list(c[x]) for x in df.astype(bool).to_numpy()], index=df.index)
对每一行应用简单的列表理解 (axis=1
) 是可行的。如果行中没有非零元素,将生成一个空列表。
df.apply(lambda row: [df.columns[i] for i, el in enumerate(row) if el], axis=1)
结果
foo [item1, item2]
bar [item2, item3]
qux []
dtype: object
我有,我认为这是一个非常普遍的问题。即,在节点列表的列表中重铸二分邻接矩阵。在 Pandas 中,这意味着从特定的 pd.DataFrame
格式转换为特定的 pd.Series
格式。
对于非离散数学人员,这看起来像以下转换:
来自
df = pd.DataFrame(columns=['item1','item2','item3'],
index=['foo','bar','qux'],
data = [[1,1,0],[0,1,1],[0,0,0]])
看起来像
item1 item2 item3
foo 1 1 0
bar 0 1 1
qux 0 0 0
到
srs = pd.Series([['item1','item2'],['item2','item3'],[]],index=['foo','bar','qux'])
看起来像
foo [item1, item2]
bar [item2, item3]
qux []
dtype: object
我已经通过以下代码部分实现了这个目标:
df_1 = df.stack().reset_index()
srs = df_1.loc[df_1[0]==1].groupby('level_0')['level_1'].apply(list)
除了有点不可读之外,还存在一路上掉落的问题 qux
。
是否有到达所需结果的更短路径?
如果想避免通过 stack
和 groupby
进行重塑,可以使用列表理解将 0,1
转换为 DataFrame.astype
的布尔值,然后过滤列名称,最后一次它到 Series
构造函数:
print([list(df.columns[x]) for x in df.astype(bool).to_numpy()])
[['item1', 'item2'], ['item2', 'item3'], []]
s = pd.Series([list(df.columns[x]) for x in df.astype(bool).to_numpy()], index=df.index)
print(s)
foo [item1, item2]
bar [item2, item3]
qux []
dtype: object
如果性能也很重要,请使用:
c = df.columns.to_numpy()
s = pd.Series([list(c[x]) for x in df.astype(bool).to_numpy()], index=df.index)
对每一行应用简单的列表理解 (axis=1
) 是可行的。如果行中没有非零元素,将生成一个空列表。
df.apply(lambda row: [df.columns[i] for i, el in enumerate(row) if el], axis=1)
结果
foo [item1, item2]
bar [item2, item3]
qux []
dtype: object