首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Pandas应用于多索引列

问Pandas应用于多索引列
EN

Stack Overflow用户
提问于 2021-11-20 22:16:17
回答 2查看 31关注 0票数 0

我有以下工作代码,可以创建一些简单的数学函数和一个具有多索引列的DataFrame。我想有条件地在它上面应用一些函数。

代码语言:javascript
复制
import pandas as pd
import numpy as np

# Simple maths functions  ---
def add(scalars): return sum(scalars)  #Adds every element in scalars
def sub(scalars): return (scalars[0] - sum(scalars[1:])) #First scalar value subtracted by the rest of the scalar list
def mul(scalars): return np.prod(scalars) #Multiplies every element in scalars
def divi(scalars): return (scalars[0] / np.prod(scalars[1:])) #First scalar value divided by the rest product of the scalar list
代码语言:javascript
复制
# Create df ---

operatorList = [add, sub, mul, divi]  # List of our maths functions
names = ['add', 'sub', 'mul', 'divi'] # List of the names of our maths functions
size = 4

tups = [('scalars', 'add', 'sc0'), ('scalars', 'add', 'sc1'), ('scalars', 'add', 'sc2'), ('scalars', 'sub', 'sc0'), ('scalars', 'sub', 'sc1'), ('scalars', 'mul', 'sc0'), ('scalars', 'mul', 'sc1'), ('scalars', 'mul', 'sc2'), ('scalars', 'divi', 'sc0'), ('scalars', 'divi', 'sc1'), ('operator', '', '')]
df = pd.DataFrame(columns=pd.MultiIndex.from_tuples(tups))

df['operatorIndex'] = np.random.randint(0, len(names), size)
df['operator'] = df['operatorIndex'].apply(lambda x: str(names[x]))

groupSize = 2
df['ID']=np.divmod(np.arange(len(df)),groupSize)[0]+1
df.set_index('ID', inplace=True)
df.sort_index(inplace=True)

for name in names:
  df.loc[(df['operator'] == name), ('scalars', name, df.columns.levels[2])] = np.random.randint(0, 10)
代码语言:javascript
复制
> df

    scalars                                   operator  operatorIndex
    add         sub     mul         divi        
    sc0 sc1 sc2 sc0 sc1 sc0 sc1 sc2 sc0 sc1     
ID                                              
1   4   4   4   NaN NaN NaN NaN NaN NaN NaN   add       0
1   NaN NaN NaN 7   7   NaN NaN NaN NaN NaN   sub       1
2   NaN NaN NaN NaN NaN 3   3   3   NaN NaN   mul       2
2   NaN NaN NaN 7   7   NaN NaN NaN NaN NaN   sub       1

如何创建一个名为Evaluation的新列,它是每个列的正确数学函数的结果?列operator告诉每一行需要应用哪个函数。

一个目标df示例如下所示:

代码语言:javascript
复制
> df

    scalars                                   operator  operatorIndex  Evaluation
    add         sub     mul         divi        
    sc0 sc1 sc2 sc0 sc1 sc0 sc1 sc2 sc0 sc1     
ID                                              
1   4   5   6   NaN NaN NaN NaN NaN NaN NaN   add       0              15
1   NaN NaN NaN 7   2   NaN NaN NaN NaN NaN   sub       1              5
2   NaN NaN NaN NaN NaN 1   2   3   NaN NaN   mul       2              6
2   NaN NaN NaN 5   9   NaN NaN NaN NaN NaN   sub       1              -4
EN

回答 2

Stack Overflow用户

发布于 2021-11-20 22:58:25

这样就行了:

代码语言:javascript
复制
df['Evaluation'] = df['operatorIndex'].apply(lambda operatorIndex: operatorList[operatorIndex](df['scalars'][names[operatorIndex]].min()))

虽然它只有在每个操作符只有一个条目时才能工作-如果一个操作在df中有多行,它将产生奇怪的结果。

您可以通过存储为每一行更新的全局计数器,并使用iloc按索引访问标量行来修复此问题:

代码语言:javascript
复制
rowCounter = -1
def func(operatorIndex):
    global rowCounter
    rowCounter += 1
    return operatorList[operatorIndex](df['scalars'][names[operatorIndex]].iloc[rowCounter])

df['Evaluation'] = df['operatorIndex'].apply(func)
票数 0
EN

Stack Overflow用户

发布于 2021-11-21 18:41:14

我设法改编了@user17242583的答案

代码语言:javascript
复制
df['Evaluation'] = df.apply(lambda row: operatorList[row['operatorIndex'].values[0]](row['scalars'][names[row['operatorIndex'].values[0]]].to_numpy()) , axis=1 )

我不知道这对其他人是否有用,但这是给你的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70050283

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档