繁体   English   中英

写一个function对一个Pandas中的多列进行计算 dataframe

[英]Write a function to perform calculations on multiple columns in a Pandas dataframe

我有以下dataframe(真实的有更多的列和行,因此仅以此为例):

 {'sample': {0: 'orange', 1: 'orange', 2: 'banana', 3: 'banana'},
 'sample id': {0: 1, 1: 1, 2: 5, 3: 5},
 'replicate': {0: 1, 1: 2, 2: 1, 3: 2},
 'taste': {0: 1.2, 1: 4.6, 2: 35.4, 3: 0.005},
 'smell': {0: 20.0, 1: 23.0, 2: 2.1, 3: 5.3},
 'shape': {0: 0.004, 1: 0.2, 2: 0.12, 3: 11.0},
 'volume': {0: 23, 1: 23, 2: 23, 3: 23},
 'weight': {0: 12.0, 1: 1.3, 2: 2.4, 3: 3.2}}

我想写一个 function 来对特定列的 dataframe 执行计算。 计算在下面的代码中。 因为我只想将代码应用于特定的列,所以我设置了一个列列表,并且由于有一个预定义的“因素”我们需要在计算中考虑在内,所以我也进行了设置:

cols = ['taste', 'smell', 'shape']
factor = 72

def multiply_columns(row):
    return ((row[cols] / row['volume']) * (factor * row['volume'] / row['weight']) / 1000)

然后,我将 function 应用到 dataframe,我想用新值覆盖原始列值,所以我这样做:

for cols in df.columns:
    df[cols] = df[cols].apply(multiply_columns)

但我收到以下错误:

~\AppData\Local\Temp/ipykernel_8544/3939806184.py in multiply_columns(row)
      3 
      4 def multiply_columns(row):
----> 5     return ((row[cols] / row['volume']) * (factor * row['volume'] / row['weight']) / 1000)
      6 
      7 

TypeError: string indices must be integers

但是我在计算中使用的值不是字符串:

sample        object
sample id      int64
replicate      int64
taste        float64
smell        float64
shape        float64
volume         int64
weight       float64
dtype: object

所需的 output 将是:

{'sample': {0: 'orange', 1: 'orange', 2: 'banana', 3: 'banana'},
 'sample id': {0: 1, 1: 1, 2: 5, 3: 5},
 'replicate': {0: 1, 1: 2, 2: 1, 3: 2},
 'taste': {0: 0.0074, 1: 0.028366667, 2: 0.2183, 3: 3.08333e-05},
 'smell': {0: 0.123333333, 1: 0.141833333, 2: 0.01295, 3: 0.032683333},
 'shape': {0: 2.46667e-05, 1: 0.001233333, 2: 0.00074, 3: 0.067833333},
 'volume': {0: 23, 1: 23, 2: 23, 3: 23},
 'weight': {0: 12.0, 1: 1.3, 2: 2.4, 3: 3.2}}

任何人都可以告诉我我的方式的错误

这有几个问题。

如果你想索引行中的元素,你使用的索引是一个字符串(列名)而不是 integer(如索引)。 要获取您感兴趣的列名的索引,您可以使用:

cols = ['taste', 'smell', 'shape']
cols_idx = [df.columns.get_loc(col) for col in cols]

但是,如果我理解您的问题,您可以直接在列上执行此操作,并理解该操作将在每一行上执行。 查看对我有用的测试用例:

import pandas as pd

df = pd.DataFrame({'sample': {0: 'orange', 1: 'orange', 2: 'banana', 3: 'banana'},
 'sample id': {0: 1, 1: 1, 2: 5, 3: 5},
 'replicate': {0: 1, 1: 2, 2: 1, 3: 2},
 'taste': {0: 1.2, 1: 4.6, 2: 35.4, 3: 0.005},
 'smell': {0: 20.0, 1: 23.0, 2: 2.1, 3: 5.3},
 'shape': {0: 0.004, 1: 0.2, 2: 0.12, 3: 11.0},
 'volume': {0: 23, 1: 23, 2: 23, 3: 23},
 'weight': {0: 12.0, 1: 1.3, 2: 2.4, 3: 3.2}})

cols = ['taste', 'smell', 'shape']

factor = 72

for col in cols:
    df[col] = ((df[col] / df['volume']) * (factor * df['volume'] / df['weight']) / 1000)

请注意,您的行

for cols in df.columns:

指示您应该在每一列上运行此操作(cols 成为索引,不再是您的列表)。

您还必须将该列传递给 function。

cols = ['taste', 'smell', 'shape']
factor = 72
def multiply_columns(row,col):
    return ((row[col]/ row['volume']) * (factor * row['volume'] / row['weight']) / 1000)

for col in cols:
    df[col] = df.apply(lambda x:multiply_columns(x,col),axis=1)

另外,我得到的 output 与您想要的 output 有点不同,即使我使用了相同的公式。

 sample sample id   replicate   taste   smell   shape   volume  weight
0   orange  1   1   0.00720000000   0.12000000000   0.00002400000   23  12.00000000000
1   orange  1   2   0.25476923077   1.27384615385   0.01107692308   23  1.30000000000
2   banana  5   1   1.06200000000   0.06300000000   0.00360000000   23  2.40000000000
3   banana  5   2   0.00011250000   0.11925000000   0.24750000000   23  3.20000000000 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM