将 Pandas 中某一列的值转换为列标题

21
我有以下代码,它将pandas数据框的一列值变为新数据框的列。 数据框的第一列中的值成为新数据框的索引。
在某种程度上,我想将邻接表转换为邻接矩阵。 到目前为止,这是代码:
import pandas as pa
# Create a dataframe
oldcols = {'col1':['a','a','b','b'], 'col2':['c','d','c','d'], 'col3':[1,2,3,4]}
a = pa.DataFrame(oldcols)

# The columns of the new data frame will be the values in col2 of the original
newcols = list(set(oldcols['col2']))
rows = list(set(oldcols['col1']))

# Create the new data matrix
data = np.zeros((len(rows), len(newcols)))

# Iterate over each row and fill in the new matrix
for row in zip(a['col1'], a['col2'], a['col3']):
    rowindex = rows.index(row[0])
    colindex = newcols.index(row[1])
    data[rowindex][colindex] = row[2]

newf = pa.DataFrame(data)
newf.columns = newcols
newf.index = rows

这个针对特定情况的方法如下:原始数据框

  col1 col2  col3
0    a    c     1
1    a    d     2
2    b    c     3
3    b    d     4

被转化为一个新的类似于DataFrame的数据结构。

   c  d
a  1  2
b  3  4

如果col3中的值不是数字,它将失败。我的问题是,是否有更优雅/健壮的方法来解决这个问题?

3个回答

33

这看起来像是透视表的工作

import pandas as pd
oldcols = {'col1':['a','a','b','b'], 'col2':['c','d','c','d'], 'col3':[1,2,3,4]}
a = pd.DataFrame(oldcols)  

newf = a.pivot(index='col1', columns='col2')
print(newf)
产生。
      col3   
col2     c  d
col1         
a        1  2
b        3  4

如果你不想要一个多级索引列,你可以使用以下代码删除col3:

newf.columns = newf.columns.droplevel(0)

这将产生

col2  c  d
col1      
a     1  2
b     3  4

哇,这几乎让我后悔手动编写代码了 :-P - juniper-
4
不用担心,这会让你更加欣赏熊猫! - unutbu
@unutbu 我的情况几乎相同,但是有重复项,我该如何处理它们。因此,这意味着如果col2有重复项,那么在这种情况下需要做什么。 - LOrD_ARaGOrN
1
@RishiBansal:当有重复值时,请使用df.pivot_table。它有一个aggfunc参数,允许您指定如何将重复值聚合为单个值。或者,在调用df.pivot之前,您可以删除重复项 - unutbu

0
如@unutbu所提到的,您可以使用来重塑数据框架。
res = a.pivot(index='col1', columns='col2', values='col3')

更简洁的方法是将列标签作为参数解包。

res = a.pivot(*a).rename_axis(index=None, columns=None)

res


另一种方法是显式构造图形对象(使用流行的图形库networkx),并构造邻接矩阵。对于简单的数据透视操作而言,这可能过于冗长,但如果给定的数据已经以图形形式存在,这种方法可能会很有用。
import networkx as nx
g = nx.Graph()
col1 = a['col1'].unique()
col2 = a['col2'].unique()
g.add_weighted_edges_from(list(map(tuple, a.values)))
res = nx.to_pandas_adjacency(g).loc[col1, col2]

0

另一种方法是将前两列分配为 MultiIndex,然后对第二列进行 unstack 操作:

df = pd.DataFrame({'col1':['a','a','b','b'], 'col2':['c','d','c','d'], 'col3':[1,2,3,4]}) 
df.set_index(['col1', 'col2']).squeeze().unstack('col2')

结果是

col2  c  d
col1      
a     1  2
b     3  4

squeeze() 方法将只有一列的 DataFrame 转换为 Series。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接