Pandas - 按日期计算不同的值 - 更有效的方法?

新人来了...


我有一个名为“yes_no”的数据框,其结构如下(但它有大约 50K 条目):


      Date        Yes/No

0     2020-10-27     No

1     2020-10-27     No

2     2020-10-26    Yes

3     2020-10-26    Yes

4     2020-10-26    No

5     2020-10-25    No

6     2020-10-25    Yes

7     2020-10-25    No

8     2020-10-24    Yes

9     2020-10-24    Yes

我需要计算每个日期的“是”数量和“否”数量,并计算比率,最终得到如下结果:


     Date        Yes   No  Percentage

0   2020-10-27  1142  120    0.904913

1   2020-10-26  4112  388    0.913778

2   2020-10-25  1055   68    0.939448

3   2020-10-24  1012   86    0.921676

4   2020-10-23  1476  163    0.900549

5   2020-10-22  1633  182    0.899725

6   2020-10-21  1773  237    0.882090

7   2020-10-20  2332  246    0.904577

8   2020-10-19  2868  326    0.897934

9   2020-10-18   892  107    0.892893

10  2020-10-17   992  110    0.900181

11  2020-10-16  2106  207    0.910506

12  2020-10-15  5628  632    0.899042

13  2020-10-14  9304  937    0.908505

14  2020-10-13  8129  881    0.902220

我通过查阅字典,使用以下代码使其工作,但它非常长:


by_date = {}

for date in yes_no['Date']:

  by_date[date] = yes_no.loc[yes_no['Date'] == date]



for date in by_date:

  by_date[date] =  by_date[date]['Yes/No'].value_counts()


for date in by_date:

  if 'No' not in by_date[date]:

    by_date[date]['No'] = 0


for date in by_date:

  if 'Yes' not in by_date[date]:

    by_date[date]['Yes'] = 0


for date in by_date:

  by_date[date] = [by_date[date]['Yes'], by_date[date]['No'], (by_date[date]['Yes']/(by_date[date]['Yes'] + by_date[date]['No']))]



df_yes = pd.DataFrame(list(by_date.values()),columns = ['Yes', 'No', 'Percentage'])

df_yes['Date'] = list(by_date.keys())

df_yes = df_yes[['Date', 'Yes', 'No', 'Percentage']]

对于较小的数据帧(1-2K)它工作得很好,但是这段代码需要永远完成 50K 条目:


for date in yes_no['Date']:

  by_date[date] = yes_no.loc[yes_no['Date'] == date]

一定有更好的方法来做到这一点!


慕村9548890
浏览 43回答 4
4回答

千巷猫影

您可以使用矢量化操作更有效地完成此操作(无需显式 python 循环)。这意味着我们所有的操作都由底层 C/C++ 函数执行,以实现巨大的加速。out = (df.groupby("Date")["Yes/No"]       .value_counts()       .unstack(fill_value=0)       .rename_axis(columns=None)       .eval("percentage = Yes / (Yes + No)")      )print(out)            No  Yes  percentageDate                           2020-10-24   0    2    1.0000002020-10-25   2    1    0.3333332020-10-26   1    2    0.6666672020-10-27   2    0    0.000000脚步:df.groupby("Date")["Yes/No"]:按“日期”对数据框进行分组,然后从这些分组中选择“是/否”列.value_counts():获取此列中每个分组的每个“是”和“否”的计数。.unstack(fill_value=0):现在我们有了计数,我们将“是”和“否”放入各自的列中。.rename_axis(columns=None):我们有一个看起来很有趣的列索引名称,我个人不喜欢这些,所以我要删除它。.eval("percentage = Yes / (Yes + No)"):创建一个名为百分比的新列,并将所有“是”计数除以总响应计数(“是”+“否”)的值分配给它

慕娘9325324

# groupby date and yes/no columns and get the size# then pivot new_df = df.groupby(['Date', 'Yes/No'], as_index=False).size().pivot('Date', 'Yes/No', 'size').replace(np.nan, 0)# divide the yes column by the size of each groupnew_df['percent_yes'] = new_df['Yes'] / new_df.sum(1)print(new_df)Yes/No       No  Yes  percent_yesDate                             2020-10-24  0.0  2.0     1.0000002020-10-25  2.0  1.0     0.3333332020-10-26  1.0  2.0     0.6666672020-10-27  2.0  0.0     0.000000

倚天杖

您应该研究一下 one-hot 编码。熊猫用途pd.get_dummies我的解决方案是:df_new = pd.get_dummies(yes_no, columns=["Yes/No"]).groupby("Date").sum().rename(columns={"Yes/No_No":"No", "Yes/No_Yes":"Yes"}然后你就可以轻松计算百分比。

阿波罗的战车

有一个非常简单的方法可以做到这一点,也许还有一些更优雅的方法:import pandas as pddf = pd.DataFrame({'Yes_no': ['yes','no','yes', 'yes', 'no','yes','no','yes', 'yes', 'no','yes','no','yes', 'yes', 'no','yes','no','yes', 'yes', 'no'],    'Dates': ['2019-07-01','2019-07-01','2019-07-01', '2019-07-03', '2019-07-03','2019-07-03','2019-07-07','2019-07-07', '2019-07-07', '2019-07-07','2019-07-07','2019-07-07','2019-07-07', '2019-07-07', '2019-07-07','2019-07-07','2019-07-07','2019-07-07', '2019-07-07', '2019-07-07']})dff = df.groupby(['Yes_no','Dates'])['Yes_no'].count()dff.unstack().T要创建具有比例的额外列,只需定义一个新列dff['prop']=dff['no']/dff['yes']
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python