将 Pandas DataFrame 的行转换为列标题

192

我需要处理一些有点凌乱的数据……它里面包含了表头名称。如何从已存在的Pandas数据框中选择一行,并将其(重命名为)列标题?

我想要做的事情类似于:

header = df[df['old_header_name1'] == 'new_header_name1']

df.columns = header
6个回答

301
In [21]: df = pd.DataFrame([(1,2,3), ('foo','bar','baz'), (4,5,6)])

In [22]: df
Out[22]: 
     0    1    2
0    1    2    3
1  foo  bar  baz
2    4    5    6

将列标签设置为第2行(索引位置1)中的值:

In [23]: df.columns = df.iloc[1]

如果索引具有唯一标签,您可以使用以下方法删除第二行:

In [24]: df.drop(df.index[1])
Out[24]: 
1 foo bar baz
0   1   2   3
2   4   5   6

如果索引不唯一,您可以使用:

In [133]: df.iloc[pd.RangeIndex(len(df)).drop(1)]
Out[133]: 
1 foo bar baz
0   1   2   3
2   4   5   6

使用df.drop(df.index[1])会删除所有标签与第二行相同的行。由于非唯一索引可能会导致类似这样的障碍(或潜在的错误),因此最好确保索引是唯一的(即使Pandas不需要)。


非常感谢您的快速回复!我该如何选择一行而不是索引位置来使其成为标题?所以对于您的示例,类似于.. df.columns = df[df[0] == 'foo'] - E.K.
问题在于可能有多行具有值“foo”。解决这个问题的一种方法是明确选择第一个这样的行:df.columns = df.iloc[np.where(df[0] == 'foo')[0][0]] - unutbu
啊,我明白你为什么这样做了。对于我的情况,我知道只有一行的值是“foo”。所以没问题。我只是按照你上面给我的方式来做了,我想这和你给我的那个是一样的。idx_loc = df[df[0] == 'foo'].index.tolist()[0] df.columns = df.iloc[idx_loc] - E.K.

115

这个版本适用(pandas v'0.19.2'):

df.rename(columns=df.iloc[0])

41
您可以通过添加.drop(df.index[0])来删除“标题”行。该操作会删除DataFrame中索引为0的行,也就是第一行,即“标题”行。 - ostrokach
2
我喜欢这个比实际被接受的答案更好。我喜欢简短的一行解决方案。 - Javier
1
请记住,在删除第一行后,索引将从1开始,因此您可能需要添加.reset_index(drop=True) - onestep.ua

37

重新创建数据框架会更容易。这也将从头开始解释列类型。

headers = df.iloc[0]
new_df  = pd.DataFrame(df.values[1:], columns=headers)

2
简单易懂。不错! - Draco D

16

重新命名标题而不重新分配df:

df.rename(columns=df.iloc[0], inplace = True)

不重新分配 df 的情况下删除行:

df.drop(df.index[0], inplace = True)

5
您可以通过read_csvread_html构造函数中的header参数指定行索引,该参数代表用作列名和数据开头的行号(s)。这样做的好处是自动删除所有之前的废弃行。
import pandas as pd
from io import StringIO

In[1]
    csv = '''junk1, junk2, junk3, junk4, junk5
    junk1, junk2, junk3, junk4, junk5
    pears, apples, lemons, plums, other
    40, 50, 61, 72, 85
    '''

    df = pd.read_csv(StringIO(csv), header=2)
    print(df)

Out[1]
       pears   apples   lemons   plums   other
    0     40       50       61      72      85

这并没有解决问题本身,问题是关于一个已经存在的“DataFrame”。 - pablete
一些发现这个问题的用户(可能是大多数)的用例比 OP 更通用;这个答案是为那个群体准备的。 - ccpizza

0

保持Python简单

Pandas DataFramescolumns属性,为什么不与标准Python一起使用呢?这样做更清晰明了:

table = [['name', 'Rf', 'Rg', 'Rf,skin', 'CRI'],
 ['testsala.cxf', '86', '95', '92', '87'],
 ['testsala.cxf: 727037 lm', '86', '95', '92', '87'],
 ['630.cxf', '18', '8', '11', '18'],
 ['Huawei stk-lx1.cxf', '86', '96', '88', '83'],
 ['dedo uv no filtro.cxf', '52', '93', '48', '58']]

import pandas as pd
data = pd.DataFrame(table[1:],columns=table[0])

或者在情况下不是第一行,而是第10行,例如:

columns = table.pop(10)
data = pd.DataFrame(table,columns=columns)

1
测试了性能,尽管我们知道创建新的DataFrame是“耗时”的。无论如何,采用这种方法花费了40倍的时间。 - gbox
@gbox 感谢您的评论!如果您想编辑答案 - G M

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