【问题标题】:Alternate method to avoid loop in pandas dataframe避免熊猫数据框中循环的替代方法
【发布时间】:2017-09-25 20:56:12
【问题描述】:

我有以下数据框:

table2 = pd.DataFrame({
        'Product Type': ['A', 'B', 'C', 'D'],
        'State_1_Value': [10, 11, 12, 13],
    'State_2_Value': [20, 21, 22, 23],
    'State_3_Value': [30, 31, 32, 33],
    'State_4_Value': [40, 41, 42, 43],
    'State_5_Value': [50, 51, 52, 53],
    'State_6_Value': [60, 61, 62, 63],
    'Lower_Bound': [-1, 1, .5, 5],
    'Upper_Bound': [1, 2, .625, 15],
    'sim_1': [0, 0, .61, 7],
    'sim_2': [1, 1.5, .7, 9],
    })

>>> table2
   Lower_Bound Product Type  State_1_Value  State_2_Value  State_3_Value  \
0         -1.0            A             10             20             30   
1          1.0            B             11             21             31   
2          0.5            C             12             22             32   
3          5.0            D             13             23             33   

   State_4_Value  State_5_Value  State_6_Value  Upper_Bound  sim_1  sim_2  
0             40             50             60        1.000    0.0    1.0  
1             41             51             61        2.000    0.0    1.5  
2             42             52             62        0.625    0.61    0.7  
3             43             53             63       15.000    7.0    9.0 

我编写了以下代码来生成一个新的 DataFrame,并为每个“sim”修改输出

for i in range(1,3):
    table2['Bucket%s'%i] = 5 * (table2['sim_%s'%i] - table2['Lower_Bound']) / (table2['Upper_Bound'] - table2['Lower_Bound']) + 1
    table2['lv'] = table2['Bucket%s'%i].map(int)
    table2['hv'] = table2['Bucket%s'%i].map(int) + 1
    table2.ix[table2['lv'] < 1 , 'lv'] = 1
    table2.ix[table2['lv'] > 5 , 'lv'] = 5
    table2.ix[table2['hv'] > 6 , 'hv'] = 6
    table2.ix[table2['hv'] < 2 , 'hv'] = 2
    table2['nLower'] = table2.apply(lambda row: row['State_%s_Value'%row['lv']],axis=1)
    table2['nHigher'] = table2.apply(lambda row: row['State_%s_Value'%row['hv']],axis=1)
    table2['Final_value_%s'%i] = (table2['nHigher'] - table2['nLower'])*(table2['Bucket%s'%i]-table2['lv']) + table2['nLower']
df = table2.filter(regex="sim|Type")

输出:

>>> df
  Product Type  sim_1  sim_2
0            A   35.0   60.0
1            B  -39.0   36.0
2            C   56.0   92.0
3            D   23.0   33.0

我想在 10,000 个模拟人上运行它,目前每个循环大约需要 0.25 秒。有没有办法修改这段代码以避免循环并提高时间效率?

编辑:如果你好奇这段代码试图完成什么,你可以在这里看到我自己回答的有点杂乱无章的问题:Pandas DataFrame: Complex linear interpolation

【问题讨论】:

  • 你能具体说明你想让代码做什么(期望的输入 -> 期望的输出)吗?现在,为了帮助您,必须有人花精力了解您编写当前代码的原因。
  • 嗨毛衣男爵,我在问题底部添加了一个链接,显示了我的代码正在完成的工作。
  • 我能够更改我们使存储桶不需要循环的代码的第一行:df.ix[:,-2:] = df.ix[:,-2: ].sub(df['Lower_Bound'],axis=0).div(df['Upper_Bound'].sub(df['Lower_Bound'],axis=0),axis=0) * 5 + 1

标签: python performance python-2.7 loops pandas


【解决方案1】:

我能够使用以下代码在没有循环的情况下完成此操作:

结果在我的 10k x 200 表上运行了 3 分钟,而不是之前的 2 小时。

不幸的是,现在我需要在 10k x 4k 的表上运行它,我在那个表上遇到了 MemoryError,但这可能超出了这个问题的范围。

df= pd.DataFrame({
            'Product Type': ['A', 'B', 'C', 'D'],
            'State_1_Value': [10, 11, 12, 13],
        'State_2_Value': [20, 21, 22, 23],
        'State_3_Value': [30, 31, 32, 33],
        'State_4_Value': [40, 41, 42, 43],
        'State_5_Value': [50, 51, 52, 53],
        'State_6_Value': [60, 61, 62, 63],
        'Lower_Bound': [-1, 1, .5, 5],
        'Upper_Bound': [1, 2, .625, 15],
        'sim_1': [0, 0, .61, 7],
        'sim_2': [1, 1.5, .7, 9],
        })


buckets = df.ix[:,-2:].sub(df['Lower_Bound'],axis=0).div(df['Upper_Bound'].sub(df['Lower_Bound'],axis=0),axis=0) * 5 + 1
low = buckets.applymap(int)
high = buckets.applymap(int) + 1
low = low.applymap(lambda x: 1 if x < 1 else x)
low = low.applymap(lambda x: 5 if x > 5 else x)
high = high.applymap(lambda x: 6 if x > 6 else x)
high = high.applymap(lambda x: 2 if x < 2 else x)
low_value = pd.DataFrame(df.filter(regex="State|Type").values[np.arange(low.shape[0])[:,None], low])
high_value = pd.DataFrame(df.filter(regex="State|Type").values[np.arange(high.shape[0])[:,None], high])
df1 = (high_value - low_value).mul((buckets - low).values) + low_value
df1['Product Type'] = df['Product Type']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-08
    • 2022-01-08
    • 2016-09-24
    • 1970-01-01
    相关资源
    最近更新 更多