【问题标题】:Get a list from Pandas DataFrame column headers从 Pandas DataFrame 列标题中获取列表
【发布时间】:2013-10-29 06:19:15
【问题描述】:

我想从 Pandas DataFrame 中获取列标题列表。 DataFrame 将来自用户输入,所以我不知道会有多少列或它们将被调用什么。

例如,如果给我一个这样的 DataFrame:

>>> my_dataframe
    y  gdp  cap
0   1    2    5
1   2    3    9
2   8    7    2
3   3    4    7
4   6    7    7
5   4    8    3
6   8    2    8
7   9    9   10
8   6    6    4
9  10   10    7

我会得到一个这样的列表:

>>> header_list
['y', 'gdp', 'cap']

【问题讨论】:

标签: python pandas dataframe


【解决方案1】:

可以通过 my_dataframe.columns 获得。

【讨论】:

  • 并由header_list = list(my_dataframe.columns)明确列出
  • ^ 或者更好:df.columns.tolist().
【解决方案2】:

您可以通过以下方式将值作为列表获取:

list(my_dataframe.columns.values)

你也可以简单地使用(如Ed Chum's answer所示):

list(my_dataframe)

【讨论】:

  • 为什么this doc 没有columns 作为属性?
  • 我会期待像 df.column_names() 这样的东西。这个答案仍然正确还是已经过时?
  • @alvas 有多种其他方法可以做到这一点(请参阅此页面上的其他答案),但据我所知,数据帧上没有直接生成列表的方法。
  • 重要的是,这会保留列顺序。
  • 第一个选项很糟糕(从当前版本的 pandas - v0.24 开始),因为它是 mixing idioms。如果您在访问 numpy 数组时遇到麻烦,请改用.tolist() 方法,它更快更习惯。
【解决方案3】:
n = []
for i in my_dataframe.columns:
    n.append(i)
print n

【讨论】:

  • 请用列表理解替换它。
  • 将前 3 行更改为 [n for n in dataframe.columns]
  • 你为什么要为了一个可以在一行中轻松完成的操作而经历所有这些麻烦?
【解决方案4】:

有一个内置方法是性能最高的:

my_dataframe.columns.values.tolist()

.columns 返回一个 Index.columns.values 返回一个数组,这有一个辅助函数 .tolist 返回一个列表。

如果性能对您来说不那么重要,Index 对象定义了一个您可以直接调用的 .tolist() 方法:

my_dataframe.columns.tolist()

性能上的区别很明显:

%timeit df.columns.tolist()
16.7 µs ± 317 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit df.columns.values.tolist()
1.24 µs ± 12.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

对于那些讨厌打字的人,您可以在df上拨打list,如下所示:

list(df)

【讨论】:

    【解决方案5】:

    DataFrame 遵循类似于 dict 的惯例,即迭代对象的“键”。

    my_dataframe.keys()
    

    创建键/列列表 - 对象方法 to_list() 和 Pythonic 方式:

    my_dataframe.keys().to_list()
    list(my_dataframe.keys())
    

    DataFrame 上的Basic iteration 返回列标签:

    [column for column in my_dataframe]
    

    不要将 DataFrame 转换为列表,只是为了获取列标签。在寻找方便的代码示例时不要停止思考。

    xlarge = pd.DataFrame(np.arange(100000000).reshape(10000,10000))
    list(xlarge) # Compute time and memory consumption depend on dataframe size - O(N)
    list(xlarge.keys()) # Constant time operation - O(1)
    

    【讨论】:

    • 我的测试显示df.columnsdf.keys() 快很多。不知道为什么它们对同一事物同时具有函数和属性(嗯,这不是我第一次看到在 pandas 中做某事的 10 种不同方法)。
    • 我回答的目的是展示几种从 DataFrame 查询列标签并突出显示性能反模式的方法。尽管如此,我还是喜欢你的 cmets 并赞成你最近的回答——因为从软件工程的角度来看,它们提供了价值。
    【解决方案6】:

    我做了一些快速测试,不出所料,使用dataframe.columns.values.tolist() 的内置版本最快:

    In [1]: %timeit [column for column in df]
    1000 loops, best of 3: 81.6 µs per loop
    
    In [2]: %timeit df.columns.values.tolist()
    10000 loops, best of 3: 16.1 µs per loop
    
    In [3]: %timeit list(df)
    10000 loops, best of 3: 44.9 µs per loop
    
    In [4]: % timeit list(df.columns.values)
    10000 loops, best of 3: 38.4 µs per loop
    

    (不过我还是很喜欢list(dataframe),所以thanks EdChum!)

    【讨论】:

      【解决方案7】:

      它变得更加简单(通过 Pandas 0.16.0):

      df.columns.tolist()
      

      会在一个不错的列表中为您提供列名。

      【讨论】:

        【解决方案8】:
        >>> list(my_dataframe)
        ['y', 'gdp', 'cap']
        

        要在调试器模式下列出数据框的列,请使用列表推导:

        >>> [c for c in my_dataframe]
        ['y', 'gdp', 'cap']
        

        顺便说一句,你可以简单地使用sorted得到一个排序列表:

        >>> sorted(my_dataframe)
        ['cap', 'gdp', 'y']
        

        【讨论】:

        • list(df) 是否仅适用于自动增量数据帧?还是适用于所有数据帧?
        • 应该为所有人工作。但是,当您在调试器中时,您需要使用列表推导 [c for c in df]
        【解决方案9】:

        挺有意思的,不过df.columns.values.tolist()的速度几乎是df.columns.tolist()的三倍,但我以为它们是一样的:

        In [97]: %timeit df.columns.values.tolist()
        100000 loops, best of 3: 2.97 µs per loop
        
        In [98]: %timeit df.columns.tolist()
        10000 loops, best of 3: 9.67 µs per loop
        

        【讨论】:

        • 时间已在this answer 中介绍。产生差异的原因是因为.values 返回底层的 numpy 数组,而用 numpy 做某事几乎总是比直接用 pandas 做同样的事情要快。
        【解决方案10】:

        在笔记本中

        对于IPython notebook 中的数据探索,我首选的方式是:

        sorted(df)
        

        这将产生一个易于阅读的按字母顺序排列的列表。

        在代码库中

        在代码中我发现这样做更明确

        df.columns
        

        因为它告诉其他阅读你的代码的人你在做什么。

        【讨论】:

        • sorted(df) 更改顺序。谨慎使用。
        • @coldspeed 我确实提到了这一点,尽管“这将产生一个易于阅读的按字母顺序排列的列表。”
        【解决方案11】:

        我觉得这个问题值得进一步解释。

        作为fixxxer noted,答案取决于您在项目中使用的 Pandas 版本。您可以使用pd.__version__ 命令获得。

        如果您出于某种原因像我一样(在 Debian 8 (Jessie) 我使用 0.14.1)使用比 0.16.0 更旧的 Pandas 版本,那么您需要使用:

        df.keys().tolist() 因为还没有实现任何df.columns 方法。

        这种keys方法的优点是它甚至可以在更新版本的Pandas中使用,所以它更通用。

        【讨论】:

        • keys() 的缺点是它是一个函数调用而不是属性查找,所以它总是会变慢。当然,对于不断的时间访问,没有人真正关心这些差异,但我认为无论如何都值得一提; df.columns 现在是更普遍接受的用于访问标题的习惯用法。
        【解决方案12】:

        作为answered by Simeon Visser,你可以这样做

        list(my_dataframe.columns.values)
        

        list(my_dataframe) # For less typing.
        

        但我认为最甜蜜的地方是:

        list(my_dataframe.columns)
        

        它是明确的,同时又不是不必要的长。

        【讨论】:

        • “它是明确的,同时又不是不必要的长。”我不同意。调用list 没有任何优点,除非您直接在df 上调用它(例如,简洁)。访问.columns 属性会返回一个Index 对象,该对象上定义了tolist() 方法,并且调用它比列出Index 更惯用。仅仅为了完整性而混合成语并不是一个好主意。列出从.values 获得的数组也是如此。
        【解决方案13】:

        如需快速、整洁、直观的检查,请尝试以下操作:

        for col in df.columns:
            print col
        

        【讨论】:

          【解决方案14】:

          即使之前提供的解决方案很好,我也希望像 frame.column_names() 这样的东西在 Pandas 中成为一个函数,但既然不是,也许使用以下语法会很好。通过调用“tolist”函数,它以某种方式保留了您以正确方式使用 pandas 的感觉:frame.columns.tolist()

          frame.columns.tolist()
          

          【讨论】:

          • Re“解决方案”:你指的是哪一个?还是您参考了几种解决方案?
          【解决方案15】:

          扩展的可迭代解包(Python 3.5+):[*df] 和朋友

          Unpacking generalizations (PEP 448) 已在 Python 3.5 中引入。所以,下面的操作都是可以的。

          df = pd.DataFrame('x', columns=['A', 'B', 'C'], index=range(5))
          df
          
             A  B  C
          0  x  x  x
          1  x  x  x
          2  x  x  x
          3  x  x  x
          4  x  x  x
          

          如果你想要list....

          [*df]
          # ['A', 'B', 'C']
          

          或者,如果你想要set

          {*df}
          # {'A', 'B', 'C'}
          

          或者,如果你想要tuple

          *df,  # Please note the trailing comma
          # ('A', 'B', 'C')
          

          或者,如果您想将结果存储在某处,

          *cols, = df  # A wild comma appears, again
          cols
          # ['A', 'B', 'C']
          

          ...如果您是那种将咖啡转换为打字声音的人,那么这会更有效地消耗您的咖啡;)

          P.S.:如果性能很重要,你会想要放弃 上面的解决方案有利于

          df.columns.to_numpy().tolist()
          # ['A', 'B', 'C']
          

          这类似于Ed Chum's answer,但更新为 v0.24 其中.to_numpy() 优于.values。看 this answer(由我)了解更多信息。

          目视检查

          由于我在其他答案中看到了这一点,因此您可以使用可迭代解包(无需显式循环)。

          print(*df)
          A B C
          
          print(*df, sep='\n')
          A
          B
          C
          

          对其他方法的批判

          对于可以在一行中完成的操作,不要使用显式的 for 循环(list comprehensions 可以)。

          接下来,使用sorted(df) 不会保留列的原始顺序。为此,您应该改用list(df)

          接下来,list(df.columns)list(df.columns.values) 是糟糕的建议(截至当前版本,v0.24)。 Index(从 df.columns 返回)和 NumPy 数组(从 df.columns.values 返回)都定义了更快、更惯用的 .tolist() 方法。

          最后,列表化(即list(df))只能作为上述 Python 3.4 或更早版本的方法的简洁替代方法,在扩展解包不可用的情况下。

          【讨论】:

            【解决方案16】:
            %%timeit
            final_df.columns.values.tolist()
            948 ns ± 19.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
            
            %%timeit
            list(final_df.columns)
            14.2 µs ± 79.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
            
            %%timeit
            list(final_df.columns.values)
            1.88 µs ± 11.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
            
            %%timeit
            final_df.columns.tolist()
            12.3 µs ± 27.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
            
            %%timeit
            list(final_df.head(1).columns)
            163 µs ± 20.6 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
            

            【讨论】:

            • 解释一下。例如,总结和结论是什么?请通过editing (changing) your answer 回复,而不是在 cmets 中(without "Edit:"、"Update:" 或类似的 - 答案应该看起来像是今天写的)。
            【解决方案17】:

            如果 DataFrame 恰好有一个 Index 或 MultiIndex 并且您希望它们也包含在列名中:

            names = list(filter(None, df.index.names + df.columns.values.tolist()))
            

            它避免了调用 reset_index() 对这样一个简单的操作有不必要的性能影响。

            我经常需要这个,因为我正在从数据库中传输数据,其中数据帧索引映射到主键/唯一键,但实际上对我来说只是另一个“列”。对于 pandas 来说,为这样的事情提供一个内置方法可能是有意义的(我完全有可能错过了它)。

            【讨论】:

              【解决方案18】:

              listHeaders = [colName for colName in my_dataframe]

              【讨论】:

              • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
              猜你喜欢
              • 2013-10-07
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多