如何制作好重现熊猫的例子

花了相当多的时间观看SO上的r和pandas标签,我得到的印象是pandas问题不太可能包含可再现的数据。 这是R社区在鼓励方面做得非常好的原因,并且由于这样的指导,新人能够在将这些例子放在一起时得到一些帮助。 能够阅读这些指南并返回可复制数据的人通常会有更好的运气来获得他们的问题的答案。

我们如何为pandas问题创建好的重现性示例? 简单的数据框可以放在一起,例如:

import pandas as pd
df = pd.DataFrame({'user': ['Bob', 'Jane', 'Alice'], 
                   'income': [40000, 50000, 42000]})

但是很多示例数据集都需要更复杂的结构,例如:

  • datetime指数或数据
  • 多个分类变量(是否有与R的expand.grid()函数等价的函数,它可以产生某些给定变量的所有可能组合?)
  • MultiIndex或Panel数据
  • 对于使用几行代码很难模拟的数据集,是否有与R的dput()相当的dput() ,允许您生成可复制粘贴的代码以重新生成数据结构?


    注意:这里的想法对于StackOverflow来说非常通用,实际上是问题。

    免责声明:写一个好问题很难。

    好:

  • 包括小*示例DataFrame,或者作为可运行代码:

    In [1]: df = pd.DataFrame([[1, 2], [1, 3], [4, 6]], columns=['A', 'B'])
    

    或者使用pd.read_clipboard(sep='ss+')将其设置为“复制和粘贴”,您可以格式化StackOverflow突出显示的文本并使用Ctrl + K(或在每行预先添加四个空格):

    In [2]: df
    Out[2]: 
       A  B
    0  1  2
    1  1  3
    2  4  6
    

    自己测试pd.read_clipboard(sep='ss+')

    *我确实意味着很小 ,绝大多数示例数据框可能少于6行所需的行数, 我打赌我可以在5行中完成。 你是否可以用df = df.head()重现错误,如果不是这样的话,看看你是否可以组成一个小型的DataFrame来展示你正面临的问题。

    *每条规则都有一个例外,明显的是性能问题(在这种情况下肯定使用%timeit和%prun),您应该在那里生成(考虑使用np.random.seed,因此我们有完全相同的框架): df = pd.DataFrame(np.random.randn(100000000, 10)) 。 说,“让我的代码快”不是严格的网站主题...

  • 写出你想要的结果(与上面类似)

    In [3]: iwantthis
    Out[3]: 
       A  B
    0  1  5
    1  4  6
    

    解释数字来自哪里:5是A为1的行的B列的总和。

  • 显示你已经尝试过的代码:

    In [4]: df.groupby('A').sum()
    Out[4]: 
       B
    A   
    1  5
    4  6
    

    但是说出什么是不正确的:A列在索引而不是列中。

  • 显示你已经做了一些研究(搜索文档,搜索StackOverflow),给出一个总结:

    总和的文档字符串简单地陈述“计算组值的总和”

    groupby文档没有给出任何示例。

    除此之外:这里的答案是使用df.groupby('A', as_index=False).sum()

  • 如果您有Timestamp列是相关的,例如您正在重新采样或其他东西,那么请明确并将pd.to_datetime应用于它们以获得更好的衡量**。

    df['date'] = pd.to_datetime(df['date']) # this column ought to be date..
    

    **有时候这是问题本身:它们是字符串。

  • 坏:

  • 不包括我们无法复制和粘贴的MultiIndex(见上文),这是对熊猫默认显示的一种委屈,但仍令人讨厌:

    In [11]: df
    Out[11]:
         C
    A B   
    1 2  3
      2  6
    

    正确的方法是用一个set_index调用包含一个普通的set_index

    In [12]: df = pd.DataFrame([[1, 2, 3], [1, 2, 6]], columns=['A', 'B', 'C']).set_index(['A', 'B'])
    
    In [13]: df
    Out[13]: 
         C
    A B   
    1 2  3
      2  6
    
  • 在提供你想要的结果时提供洞察力:

       B
    A   
    1  1
    5  0
    

    具体说明你是如何得到这些数字的(他们是什么)......仔细检查他们是否正确。

  • 如果你的代码抛出一个错误,那么包含整个堆栈跟踪(如果它太嘈杂,可以稍后编辑它)。 显示行号(以及与之对应的代码的相应行)。

  • 丑陋的:

  • 不要链接到我们无法访问的csv(理想情况下根本不要链接到外部源......)

    df = pd.read_csv('my_secret_file.csv')  # ideally with lots of parsing options
    

    大多数数据是专有的,我们得到的是:组成类似的数据,看看你是否可以重现这个问题(小的东西)。

  • 不要用文字模糊地解释这种情况,就像你有一个“大”的DataFrame一样,在传递中提及一些列名(确保不提及它们的dtype)。 尝试并在没有看到实际情景的情况下进入许多完全没有意义的细节。 据推测,没有人甚至会读到本段末尾。

    散文很糟糕,小例子更容易。

  • 在解决实际问题之前,不要包含10+(100+ ??)个数据线路。

    请在我们的日常工作中看到足够的这一点。 我们想帮忙,但不是这样....
    切入介绍,并在导致您遇到问题的步骤中显示相关的DataFrame(或其小版本)。

  • 无论如何,玩得开心学习python,numpy和熊猫!


    如何创建示例数据集

    这主要是通过提供如何创建示例数据框的示例来扩展@ AndyHayden的答案。 大熊猫和(尤其是)numpy为您提供了多种工具,通常只需几行代码即可创建任何真实数据集的合理传真。

    在导入numpy和pandas之后,如果你想让人们能够精确地再现你的数据和结果,一定要提供一个随机种子。

    import numpy as np
    import pandas as pd
    
    np.random.seed(123)
    

    厨房水槽的例子

    下面是一个例子,展示你可以做的各种事情。 各种有用的示例数据框可以从这个子集创建:

    df = pd.DataFrame({ 
    
        # some ways to create random data
        'a':np.random.randn(6),
        'b':np.random.choice( [5,7,np.nan], 6),
        'c':np.random.choice( ['panda','python','shark'], 6),
    
        # some ways to create systematic groups for indexing or groupby
        # this is similar to r's expand.grid(), see note 2 below
        'd':np.repeat( range(3), 2 ),
        'e':np.tile(   range(2), 3 ),
    
        # a date range and set of random dates
        'f':pd.date_range('1/1/2011', periods=6, freq='D'),
        'g':np.random.choice( pd.date_range('1/1/2011', periods=365, 
                              freq='D'), 6, replace=False) 
        })
    

    这产生:

              a   b       c  d  e          f          g
    0 -1.085631 NaN   panda  0  0 2011-01-01 2011-08-12
    1  0.997345   7   shark  0  1 2011-01-02 2011-11-10
    2  0.282978   5   panda  1  0 2011-01-03 2011-10-30
    3 -1.506295   7  python  1  1 2011-01-04 2011-09-07
    4 -0.578600 NaN   shark  2  0 2011-01-05 2011-02-27
    5  1.651437   7  python  2  1 2011-01-06 2011-02-03
    

    一些说明:

  • np.repeatnp.tilede列)对于以非常规的方式创建组和索引非常有用。 对于2列,这可以用来轻松复制r的expand.grid()但是也可以更灵活地提供所有排列的子集。 但是,对于3列或更多列,语法很快变得笨拙。
  • 要更直接地替换r的expand.grid()请参阅pandas cookbook中的itertools解决方案或此处显示的np.meshgrid解决方案。 这些将允许任何数量的维度。
  • 你可以用np.random.choice做很多np.random.choice 。 例如,在g列中,我们从2011年开始随机选择6个日期。另外,通过设置replace=False我们可以确保这些日期是唯一的 - 如果我们想将其用作具有唯一值的索引,则非常方便。
  • 假股票市场数据

    除了上述代码的子集之外,您还可以将这些技术进一步结合以完成任何事情。 例如,下面是一个简短的例子,它结合了np.tiledate_range来为覆盖相同日期的4只股票创建样本股票数据:

    stocks = pd.DataFrame({ 
        'ticker':np.repeat( ['aapl','goog','yhoo','msft'], 25 ),
        'date':np.tile( pd.date_range('1/1/2011', periods=25, freq='D'), 4 ),
        'price':(np.random.randn(100).cumsum() + 10) })
    

    现在我们有一个包含100行(每个行情25个日期)的示例数据集,但我们只使用了4行来完成此工作,使其他人无需复制和粘贴100行代码便可轻松进行复制。 然后,您可以显示数据的子集,如果它有助于解释您的问题:

    >>> stocks.head(5)
    
            date      price ticker
    0 2011-01-01   9.497412   aapl
    1 2011-01-02  10.261908   aapl
    2 2011-01-03   9.438538   aapl
    3 2011-01-04   9.515958   aapl
    4 2011-01-05   7.554070   aapl
    
    >>> stocks.groupby('ticker').head(2)
    
             date      price ticker
    0  2011-01-01   9.497412   aapl
    1  2011-01-02  10.261908   aapl
    25 2011-01-01   8.277772   goog
    26 2011-01-02   7.714916   goog
    50 2011-01-01   5.613023   yhoo
    51 2011-01-02   6.397686   yhoo
    75 2011-01-01  11.736584   msft
    76 2011-01-02  11.944519   msft
    

    答复者的日记

    我提出问题的最好建议是发挥回答问题的人的心理。 作为这些人之一,我可以深入了解为什么我回答某些问题,以及为什么我不回答其他人。

    动机

    出于几个原因,我有动力回答问题

  • Stackoverflow.com一直是我非常宝贵的资源。 我想回报。
  • 在我回馈的努力中,我发现这个网站比以前更强大。 回答问题对我来说是一种学习体验,我喜欢学习。 阅读这个答案,并从另一位兽医评论。 这种互动让我开心。
  • 我喜欢分数!
  • 见#3。
  • 我喜欢有趣的问题。
  • 我所有的最纯粹的意图都是伟大的,但如果我回答1个问题或30个问题,我会得到满意的结果。 是什么促使我选择哪个问题来回答问题,这是最大化问题的一个重要组成部分。

    我也会把时间花在有趣的问题上,但这种情况很少,也不会帮助那些需要解决非趣味问题的提问者。 让我回答一个问题的最好方法就是在一个成熟的拼盘上提出这个问题,以尽可能小的努力回答它。 如果我正在看两个问题,一个有代码,我可以复制粘贴来创建我需要的所有变量......我正在拿那个! 也许,如果我有时间的话,我会回到另一个。

    主要建议

    让人们回答问题变得容易。

  • 提供创建所需变量的代码。
  • 最小化该代码。 如果在看帖子时我的眼睛黯然失色,我就会回到下一个问题或回到我正在做的其他事情上。
  • 想想你在问什么,具体是什么。 我们想看看你做了什么,因为自然语言(英语)是不精确和令人困惑的。 您尝试过的代码示例有助于解决自然语言描述中的不一致问题。
  • 请显示你的期望! 我必须坐下来试一下。 我几乎从不知道某个问题的答案,而没有尝试一些事情。 如果我没有看到你正在寻找的例子,我可能会传递这个问题,因为我不喜欢猜测。
  • 您的声誉不仅仅是您的声誉。

    我喜欢积分(我在上面提到过)。 但这些点并不真的是我的名声。 我真正的声誉是网站上的其他人认为我的合并。 我力求公平和诚实,我希望别人能看到这一点。 对提问者来说意味着什么,我们记得提问者的行为。 我记得,如果你不选择答案并且提出好的答案。 如果你以我不喜欢的方式或以我喜欢的方式行事,我记得。 这也涉及到我会回答的问题。


    无论如何,我可能会继续下去,但我会让所有真正阅读过这些内容的人都饶有兴趣。

    链接地址: http://www.djcxy.com/p/24885.html

    上一篇: How to make good reproducible pandas examples

    下一篇: How do I replace NA values with zeros in an R dataframe?