【问题标题】:How to copy/paste DataFrame from Stack Overflow into Python如何从 Stack Overflow 复制/粘贴 DataFrame 到 Python
【发布时间】:2015-10-15 03:32:22
【问题描述】:

questionsanswers 中,用户经常发布一个示例DataFrame,他们的问题/答案适用于:

In []: x
Out[]: 
   bar  foo
0    4    1
1    5    2
2    6    3

能够将这个DataFrame 输入到我的 Python 解释器中非常有用,这样我就可以开始调试问题或测试答案。

我该怎么做?

【问题讨论】:

    标签: python pandas clipboard


    【解决方案1】:

    pd.read_clipboard() 很漂亮。但是,如果您是在脚本或笔记本中编写代码(并且您希望您的代码在未来可以正常工作),那么这不是一个很好的选择。这是将数据框的输出复制/粘贴到新数据框对象中的另一种方法,可确保 df 的寿命比剪贴板的内容长:

    # py3 only, see below for py2
    import pandas as pd
    from io import StringIO
    
    d = '''0   1   2   3   4
    A   Y   N   N   Y
    B   N   Y   N   N
    C   N   N   N   N
    D   Y   Y   N   Y
    E   N   Y   Y   Y
    F   Y   Y   N   Y
    G   Y   N   N   Y'''
    
    df = pd.read_csv(StringIO(d), sep='\s+')
    

    几点说明:

    • 三引号字符串保留输出中的换行符。
    • StringIO 将输出包装在类似文件的对象中,read_csv 需要这样做。
    • sep 设置为\s+ 使得每个连续的空白块都被视为一个分隔符。

    更新

    以上答案仅适用于 Python 3。如果您卡在 Python 2 中,请替换导入行:

    from io import StringIO
    

    改为:

    from StringIO import StringIO
    

    如果您有旧版本的 pandasv0.24 或更早版本),有一种简单的方法可以编写上述代码的 Py2/Py3 兼容版本:

    import pandas as pd
    
    d = ...
    df = pd.read_csv(pd.compat.StringIO(d), sep='\s+')
    

    pandas 的最新版本已删除 compat 模块以及 Python 2 支持。

    【讨论】:

    • 最好使用pd.compat.StringIO,那么就没有必要from io import StringIO
    • 在 Python 3 中它完全没有区别(pd.compat.StringIO is io.StringIOTrue),只是风格问题(导入语句与更长的参数)。但是,我刚刚检查过,结果发现在 Python 2 中使用 io.StringIO 会导致一个讨厌的 bytesunicode 问题。我会说这绝对是一个比另一个更喜欢一个的充分理由,所以我将更改我的答案以使用pd.compat.StringIO
    • 您缺少导入:根据您的 Python 版本,即from StringIO import StringIO 用于 Python 2,from io import StringIO 用于 Python 3,如 pandas.pydata.org/pandas-docs/stable/user_guide/io.html 中所述。由于github.com/pydata/pandas-datareader/issues/655,使用 pandas 0.25.0 导入将失败。解决方案是回滚到以前的熊猫版本:pip3 install --upgrade pandas==0.24.2
    • @Harvey 显然,pandas >= 0.25.0 已经放弃了 compat 模块,以及 Python 2 支持。我已经更新了我的答案以反映这一点
    【解决方案2】:

    如果您从具有如下标准条目的 CSV 文件中复制粘贴:

    2016,10,M,0600,0610,13,1020,24
    2016,3,F,0300,0330,21,6312,1
    2015,4,M,0800,0830,8,7112,30
    2015,10,M,0800,0810,19,0125,1
    2016,8,M,1500,1510,21,0910,2
    2015,10,F,0800,0810,3,8413,5
    
    df =pd.read_clipboard(sep=",", header=None)
    df.rename(columns={0: "Name0", 1: "Name1",2:"Name2",3:"Name3",4:"Name4",5:"Name5",6:"Name6",7:"Name7",8:"Name8"})
    

    会给你正确定义的熊猫数据框。

    【讨论】:

      【解决方案3】:

      Pandas 是由真正了解人们想要做什么的人编写的。

      Since version 0.13 有一个函数pd.read_clipboard 在使这个“正常工作”方面非常有效。

      复制并粘贴问题中以bar foo 开头的部分代码(即DataFrame)并在Python 解释器中执行此操作:

      In [53]: import pandas as pd
      In [54]: df = pd.read_clipboard()
      
      In [55]: df
      Out[55]: 
         bar  foo
      0    4    1
      1    5    2
      2    6    3
      

      注意事项

      • 不要包含 iPython InOut 的东西,否则它将不起作用
      • 如果你有一个命名索引,你目前需要添加engine='python'(参见GitHub上的this issue)。命名索引时,“c”引擎当前已损坏。
      • MultiIndexes 并不出色:

      试试这个:

                            0         1         2
      level1 level2                              
      foo    a       0.518444  0.239354  0.364764
             b       0.377863  0.912586  0.760612
      bar    a       0.086825  0.118280  0.592211
      

      这根本不起作用,或者这个:

                    0         1         2
      foo a  0.859630  0.399901  0.052504
          b  0.231838  0.863228  0.017451
      bar a  0.422231  0.307960  0.801993
      

      这可行,但返回的东西完全不正确!

      【讨论】:

      • 请注意,dtype 将是object,即str,因此您可能需要使用df = df.convert_objects(convert_numeric=True)
      • 这个特定示例(OP 中的示例)似乎并非如此。不过,这是一个值得提防的好方法。
      • 嗯,我之前确实观察到过,但你是对的,这确实可以正常工作
      • 我想知道如何在代码中复制和粘贴输入和输出编号,就像您在此处显示的 In [55]Out[55] 一样。我正在使用 Jupyter Notebook,但似乎找不到这样做的方法。
      猜你喜欢
      • 2018-09-04
      • 2020-10-25
      • 1970-01-01
      • 2011-04-19
      • 1970-01-01
      • 1970-01-01
      • 2011-09-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多