【问题标题】:Pandas Multiply Specific Columns by Value In RowPandas 将特定列乘以行中的值
【发布时间】:2018-10-11 19:13:20
【问题描述】:

我正在尝试为多个特定列在它们各自的行中设置一个值。

例如:

          X         Y         Z
A 10      1         0         1        
B 50      0         0         0      
C 80      1         1         1

会变成:

              X         Y         Z
A 10        10         0         10        
B 50        0          0         0      
C 80        80         80        80

我遇到的问题是使用 mul() 时超时。我的真实数据集非常大。我尝试在我的真实代码中使用循环对其进行迭代,如下所示:

for i in range(1,df_final_small.shape[0]): 
    df_final_small.iloc[i].values[3:248] = df_final_small.iloc[i].values[3:248] * df_final_small.iloc[i].values[2]

当应用于示例数据框时将如下所示:

for i in range(1,df_final_small.shape[0]): 
    df_final_small.iloc[i].values[1:4] = df_final_small.iloc[i].values[1:4] * df_final_small.iloc[i].values[0]

必须有更好的方法来做到这一点,我在弄清楚如何只将乘法转换为行中的某些列而不是整行时遇到了问题。

编辑: 在这里更详细的是我的 df.head(5)。

id  gross   150413 Welcome Email    150413 Welcome Email Repeat Cust    151001 Welcome Email    151001 Welcome Email Repeat Cust    161116 eKomi    1702 Hot Leads Email    1702 Welcome Email - All Purchases  1804 Hot Leads  ... SILVER  GOLD    PLATINUM    Acquisition Direct Mail Conversion Direct Mail  Retention Direct Mail   Retention eMail cluster x   y
0   0033333 46.2    0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 1.0 0.0 0.0 0.0 1.0 0.0 10  -0.230876   0.461990
1   0033331 2359.0  0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 ... 0.0 1.0 0.0 0.0 0.0 1.0 0.0 9   0.231935    -0.648713
2   0033332 117.0   0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 ... 0.0 1.0 0.0 0.0 0.0 1.0 0.0 5   -0.812921   -0.139403
3   0033334 89.0    0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 ... 0.0 1.0 0.0 0.0 0.0 1.0 0.0 5   -0.812921   -0.139403
4   0033335 1908.0  0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 1.0 0.0 0.0 1.0 0.0 0.0 7   -0.974142   0.145032

【问题讨论】:

  • 索引是A 50,需要从中提取数字吗?
  • 你能打印df.head(5)吗?

标签: python pandas multiplication


【解决方案1】:

只需指定要相乘的列。示例

df=pd.DataFrame({'A':10,'X':1,'Y':1,'Z':1},index=[1])
df.loc[:,['X', 'Y', 'Z']]=df.loc[:,['X', 'Y', 'Z']].values*df.iloc[:,0:1].values

如果想提供任意范围的列,请使用 iloc

range_of_columns= range(10,5001)+range(5030,10001)
df.iloc[:,range_of_columns].values*df.iloc[:,0:1].values #multiplying the range of columns with the first column

【讨论】:

  • 这是我之前所做的,但我不想在将来需要通过乘法对 10-5000 和 5030-10000 等部分进行归一化时确定超过 10,000 列。
  • 使用您的解决方案:df=pd.DataFrame({'A':10,'X':1,'Y':1,'Z':1},index=[1]) df.loc[:,['X', 'Y', 'Z']].valuesdf.iloc[:,0:1].values df = df.loc[:,['X', 'Y', 'Z']].valuesdf.iloc[:,0:1].values print df 结果是一个 numpy 数组,我想编辑整个数据框。
  • mad_ 更新更接近但未针对我的数据集运行,总列(第 2 列)已添加到您的第二个解决方案以及我想乘以详细的列范围在我的问题中尝试这里是我根据您的第二个解决方案使用的代码: range_of_columns= range(3,248) df_final_small.iloc[:,range_of_columns].values*df_final_small.iloc[:,0:2].values 输出如下: ValueError: 操作数不能与形状一起广播 (5,245) (5,2)
  • 为了澄清,我想将列 'gross' 列 2 乘以列 3 到 248。
  • mad_ 我不确定您在说什么,您能否说明您希望我进行哪些编辑?在我的 df.head(5) 中发布的索引列不是其中的一列。第 0 列是 id,第 1 列是总值。我的问题仍然存在,之前的推荐是一个错字,我的道歉应该是这样写的:为了澄清,我想将列 'gross' 列 1 乘以列 3 到 248。
【解决方案2】:

mulaxis = 0 一起使用还可以通过get_level_values 获得index

df.mul(df.index.get_level_values(1),axis=0)
Out[167]: 
       X   Y   Z
A 10  10   0  10
B 50   0   0   0
C 80  80  80  80

此外,当数据框很大时,您可以将其拆分并按块进行。

dfs = np.split(df, [2], axis=0)
pd.concat([x.mul(x.index.get_level_values(1), axis=0) for x in dfs])
Out[174]: 
       X   Y   Z
A 10  10   0  10
B 50   0   0   0
C 80  80  80  80

另外我会推荐numpy广播

df.values*df.index.get_level_values(1)[:,None]
Out[177]: Int64Index([[10, 0, 10], [0, 0, 0], [80, 80, 80]], dtype='int64')
pd.DataFrame(df.values*df.index.get_level_values(1)[:,None],index=df.index,columns=df.columns)
Out[181]: 
       X   Y   Z
A 10  10   0  10
B 50   0   0   0
C 80  80  80  80

【讨论】:

  • 我的完整数据集和测试用例都出现索引错误:IndexError: Too many levels: Index has only 1 level, not 3
  • 我认为这是另一列。只看OP的解决方案
  • RangeIndex(start=0, stop=17692, step=1)
  • 为了澄清,请查看我的原始数据集,我只想将总值乘以包含 0 或 1 的字段,还有其他列我不想乘以。现在尝试您的第三个解决方案。
  • @JosephPNardone 有点不清楚,也许考虑修复您的示例数据框
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-09-30
  • 1970-01-01
  • 2023-03-31
  • 2021-07-17
  • 2017-03-10
  • 1970-01-01
相关资源
最近更新 更多