【问题标题】:Make row operations faster in pandas在 pandas 中使行操作更快
【发布时间】:2017-01-14 21:40:26
【问题描述】:

我正在 Coursera 上上一门课程,我有一个数据集可以执行一些操作。我已经得到了问题的答案,但我的答案需要时间来计算。

Here 是原始数据集,下面提供了示例屏幕截图。

任务是将数据从月度值转换为季度值,即我需要将 2000-01、2000-02、2000-03 数据汇总到 2000-Q1 等等。 2000-Q1 的新值应该是这三个值的平均值。 同样,2000-04、2000-05、2000-06 将变为 2000-Q2,新值应为 2000-04、2000-05、2000-06 的平均值

这是我解决问题的方法。

首先我定义了一个函数quarter_rows(),它接受一行数据(作为一个系列),使用列索引遍历每三个元素,用上面解释的计算的平均值替换一些值(就地)并返回行

import pandas as pd
import numpy as np
housing = pd.read_csv('City_Zhvi_AllHomes.csv')

def quarter_rows(row):
    for i in range(0, len(row), 3):
        row.replace(row[i], np.mean(row[i:i+3]), inplace=True)
    return row

现在我对数据进行了一些子集化和清理,只留下我需要处理的内容

p = ~housing.columns.str.contains('199') # negation of columns starting with 199
housing = housing[housing.columns[p]]
housing3 = housing.set_index(["State","RegionName"]).ix[:, '2000-01' : ]

然后我使用 apply 将函数应用于所有行。

housing3 = housing3.apply(quarter_rows, axis=1)

我得到了预期的结果。示例如下所示

但整个过程需要一分钟多的时间才能完成。原始数据框大约有 10370 列。

我不知道是否有办法在 for 循环和应用函数中加快速度。我的 quarter_rows() 函数中的 for 循环占用了大部分时间。 我已经尝试过 python lambdas,但我尝试的每一种方式都抛出了异常。 我真的很想找到一种方法来使用三个连续值而不使用 for 循环来获取平均值。

谢谢

【问题讨论】:

  • 感谢编辑

标签: python pandas


【解决方案1】:

我认为您可以改用 apply 使用 resample by quarters 并聚合 mean,但首先将列名转换为 month 句点 by to_period

housing3.columns = pd.to_datetime(housing3.columns).to_period('M')
housing3 = housing3.resample('Q', axis=1).mean()

测试:

housing = pd.read_csv('City_Zhvi_AllHomes.csv')
p = ~housing.columns.str.contains('199') # negation of columns starting with 199
housing = housing[housing.columns[p]]
#for testing slect only 10 first rows and columns from jan 2000 to jun 2000
housing3 = housing.set_index(["State","RegionName"]).ix[:10, '2000-01' : '2000-06']
print (housing3)
                     2000-01   2000-02   2000-03   2000-04   2000-05   2000-06
State RegionName                                                              
NY    New York           NaN       NaN       NaN       NaN       NaN       NaN
CA    Los Angeles   204400.0  207000.0  209800.0  212300.0  214500.0  216600.0
IL    Chicago       136800.0  138300.0  140100.0  141900.0  143700.0  145300.0
PA    Philadelphia   52700.0   53100.0   53200.0   53400.0   53700.0   53800.0
AZ    Phoenix       111000.0  111700.0  112800.0  113700.0  114300.0  115100.0
NV    Las Vegas     131700.0  132600.0  133500.0  134100.0  134400.0  134600.0
CA    San Diego     219200.0  222900.0  226600.0  230200.0  234400.0  238500.0
TX    Dallas         85100.0   84500.0   83800.0   83600.0   83800.0   84200.0
CA    San Jose      364100.0  374000.0  384700.0  395700.0  407100.0  416900.0
FL    Jacksonville   88000.0   88800.0   89000.0   88900.0   89600.0   90600.0

housing3.columns = pd.to_datetime(housing3.columns).to_period('M')
housing3 = housing3.resample('Q', axis=1).mean()
print (housing3)
                           2000Q1         2000Q2
State RegionName                                
NY    New York                NaN            NaN
CA    Los Angeles   207066.666667  214466.666667
IL    Chicago       138400.000000  143633.333333
PA    Philadelphia   53000.000000   53633.333333
AZ    Phoenix       111833.333333  114366.666667
NV    Las Vegas     132600.000000  134366.666667
CA    San Diego     222900.000000  234366.666667
TX    Dallas         84466.666667   83866.666667
CA    San Jose      374266.666667  406566.666667
FL    Jacksonville   88600.000000   89700.000000

【讨论】:

  • 我想补充一点,我的问题的答案导致了另一个问题:如何将 PeriodIndex 格式的新列转换为字符串。这篇文章将帮助stackoverflow.com/questions/34800343/…
  • 好的,你可以做到。如果有帮助,您可以投票。我的或另一个答案。两者都很好。
猜你喜欢
  • 2012-12-30
  • 2019-01-29
  • 2019-09-03
  • 2022-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-01
  • 1970-01-01
相关资源
最近更新 更多