【问题标题】:Convert row to column header for Pandas DataFrame,将 Pandas DataFrame 的行转换为列标题,
【发布时间】:2014-11-26 15:17:06
【问题描述】:

我必须处理的数据有点混乱。它的数据中有标题名称。如何从现有的 pandas 数据框中选择一行并使其(重命名为)列标题?

我想做这样的事情:

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

df.columns = header

【问题讨论】:

    标签: python pandas rename dataframe


    【解决方案1】:

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

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

    删除行而不重新分配df:

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

    【讨论】:

      【解决方案2】:

      您可以通过代表Row number(s) to use as the column names, and the start of the dataheader参数在read_csvread_html构造函数中指定行索引。这样做的好处是可以自动删除前面所有被认为是垃圾的行。

      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
      

      【讨论】:

        【解决方案3】:
        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']
        • 问题在于可能不止一行的值为"foo"。解决该问题的一种方法是明确选择第一行:df.columns = df.iloc[np.where(df[0] == 'foo')[0][0]]
        • 啊,我明白你为什么那样做。就我而言,我知道只有一行的值为“foo”。所以没关系。我就是这样做的,我想它和你上面给我的一样。 idx_loc = df[df[0] == 'foo'].index.tolist()[0] df.columns = df.iloc[idx_loc]
        【解决方案4】:

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

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

        【讨论】:

        • 简单易行。不错!
        【解决方案5】:

        这有效(pandas v'0.19.2'):

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

        【讨论】:

        • 您可以通过添加.drop(df.index[0])删除“标题”行
        • 我比实际接受的答案更喜欢这个。我喜欢简短的在线解决方案。
        猜你喜欢
        • 2019-02-15
        • 2013-03-22
        • 1970-01-01
        • 2018-04-18
        • 2021-03-01
        • 2013-06-22
        • 1970-01-01
        相关资源
        最近更新 更多