Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 基于其他列中的值对某些列求平均值_Python_Dataframe_Average_Apply_Calculated Columns - Fatal编程技术网

Python 基于其他列中的值对某些列求平均值

Python 基于其他列中的值对某些列求平均值,python,dataframe,average,apply,calculated-columns,Python,Dataframe,Average,Apply,Calculated Columns,我想根据另一列中是否满足某个条件来平均某些列的值。具体地说,如果下面数据框中的第1列小于1700,我希望在我的平均计算中包含第51列中该行的相应值。如果第2列

我想根据另一列中是否满足某个条件来平均某些列的值。具体地说,如果下面数据框中的第1列小于1700,我希望在我的平均计算中包含第51列中该行的相应值。如果第2列<1700,我还想在我的平均值计算中包括第52列中该行的值

因此,对于第0行,该行的新计算列将为64(平均值为65和63)。对于第1行,平均值仅为80(第51列的值),因为第2列和第3列都不小于1700,因此不包括在平均值计算中

这是一个简化的示例,因为我的实际数据帧有大约10列用于条件,其中10列对应的平均值

作为一种潜在的复杂性,列标题是数字而不是传统的文本标签,并且不引用该列在数据框中的顺序,因为我在导入csv文件时排除了某些列。换句话说,第51列不是数据帧中的第51列

当我运行以下代码时,出现以下错误:

ValueError:(“对象类型没有命名为1的轴”, '在索引0处发生')

有没有更有效的方法来编写代码并避免此错误?谢谢你的帮助

import pandas as pd
import numpy as np

test_df = pd.DataFrame({1:[1600,1600,1600,1700,1800],2:[1500,2000,1400,1500,2000],
3:[2000,2000,2000,2000,2000],51:[65,80,75,80,75],52:[63,82,85,85,75],53:[83,80,75,76,78]})

test_df

     1     2     3   51  52  53
0  1600  1500  2000  65  63  83
1  1600  2000  2000  80  82  80
2  1600  1400  2000  75  85  75
3  1700  1500  2000  80  85  76
4  1800  2000  2000  75  75  78


def calc_mean_based_on_conditions(row):

        list_of_columns_to_average = []
        for i in range(1,4):
            if row[i] < 1700:
                list_of_columns_to_average.append(i+50)

        if not list_of_columns_to_average:
            return np.nan
        else:
            return row[(list_of_columns_to_average)].mean(axis=1)

test_df['MeanValue'] = test_df.apply(calc_mean_based_on_conditions, axis=1)
将熊猫作为pd导入
将numpy作为np导入
test_df=pd.DataFrame({1:[160017001800],2:[15002000140015002000],
3:[2000,2000,2000,2000,2000],51:[65,80,75,80,75],52:[63,82,85,85,75],53:[83,80,75,76,78]})
测试
1     2     3   51  52  53
0  1600  1500  2000  65  63  83
1  1600  2000  2000  80  82  80
2  1600  1400  2000  75  85  75
3  1700  1500  2000  80  85  76
4  1800  2000  2000  75  75  78
基于条件的def计算平均值(行):
列出所有列的平均值=[]
对于范围(1,4)内的i:
如果第[i]行小于1700:
列出\u列的\u到\u平均值。追加(i+50)
如果未列出\u列的\u至\u平均值:
返回np.nan
其他:
返回行[(列的列表到平均值)]。平均值(轴=1)
测试df['MeanValue']=测试df.apply(基于条件计算平均值,轴=1)

我删除了另一个答案,因为它走错了方向。您要做的是生成条件列的掩码,然后使用该掩码将函数应用于其他列。在这种情况下,1对应于51,2对应于52,等等

import pandas as pd
import numpy as np

test_df = pd.DataFrame({1:[1600,1600,1600,1700,1800],2:[1500,2000,1400,1500,2000],
3:[2000,2000,2000,2000,2000],51:[65,80,75,80,75],52:[63,82,85,85,75],53:[83,80,75,76,78]})

test_df

     1     2     3   51  52  53
0  1600  1500  2000  65  63  83
1  1600  2000  2000  80  82  80
2  1600  1400  2000  75  85  75
3  1700  1500  2000  80  85  76
4  1800  2000  2000  75  75  78



# create dictionary to map columns to one another
l1=list(range(1,4))
l2=list(range(50,54))
d = {k:v for k,v in zip(l1,l2)}

d
{1: 51, 2: 52, 3: 53}

temp=test_df[l1] > 1700 # Subset initial dataframe, generate mask
for _, row in temp.iterrows(): #iterate through subsetted data
    list_of_columns_for_mean=list() # list of columns for later computation
    for k, v in d.items(): #iterate through each k:v and evaluate conditional for each row
        if row[k]:
            list_of_columns_for_mean.append(v)
            # the rest should be pretty easy to figure out

这不是一个优雅的解决方案,但它是一个解决方案。不幸的是,我已经没有时间专门讨论它了,但希望这能为您指明一个更好的方向。

可能有更好的、矢量化的方法来实现这一点,但您可以不用函数来实现它

import numpy as np
import pandas as pd
from collections import defaultdict

test_df = pd.DataFrame({1:[1600,1600,1600,1700,1800],2:[1500,2000,1400,1500,2000],
3:[2000,2000,2000,2000,2000],51:[65,80,75,80,75],52:[63,82,85,85,75],53:[83,80,75,76,78]})

# List of columns that you're applying the condition to
condition_cols = list(range(1,4))

# Get row and column indices where this condition is true
condition = np.where(test_df[condition_cols].lt(1700))

# make a dictionary mapping row to true columns
cond_map = defaultdict(list)
for r,c in zip(*condition):
    cond_map[r].append(c)

# Get the means of true columns
means = []
for row in range(len(test_df)):
    if row in cond_map:
        temp = []
        for col in cond_map[row]:
            # Needs 51 because of Python indexing starting at zero + 50
            temp.append(test_df.loc[row, col+51])
        means.append(temp)
    else:
        # If the row has no true columns (i.e row 4)
        means.append(np.nan)

test_df['Means'] = [np.mean(l) for l in means]   
问题是以矢量化的方式为真正的行和列编制索引。

一些非常相关的东西(支持int作为列名)——

由于此错误/问题,我将列名转换为字符串类型:

test_df = pd.DataFrame({'1':[1600,1600,1600,1700,1800],'2':[1500,2000,1400,1500,2000],
'3':[2000,2000,2000,2000,2000],'51':[65,80,75,80,75],'52':[63,82,85,85,75],'53': 
[83,80,75,76,78]})
创建了一个新的数据框架-新的_df以满足out需求

new_df = test_df[['1', '2', '3']].where(test_df[['1','2','3']]<1700).notnull()
然后简单地重命名列并使用“where”进行检查

new_df = new_df.rename(columns={"1": "51", "2":"52", "3":"53"})
test_df['mean_value'] = test_df[['51', '52', '53']].where(new_df).mean(axis=1)
这将为您提供所需的输出-

    1     2     3  51  52  53  mean_value
0  1600  1500  2000  65  63  83        64.0
1  1600  2000  2000  80  82  80        80.0
2  1600  1400  2000  75  85  75        80.0
3  1700  1500  2000  80  85  76        85.0
4  1800  2000  2000  75  75  78         NaN

使用Pandas的
,其中
是我希望用于布尔数据帧的方法,而不是典型的系列掩码。回答得好!这回答了你的问题吗?
    1     2     3  51  52  53  mean_value
0  1600  1500  2000  65  63  83        64.0
1  1600  2000  2000  80  82  80        80.0
2  1600  1400  2000  75  85  75        80.0
3  1700  1500  2000  80  85  76        85.0
4  1800  2000  2000  75  75  78         NaN