首页 > 解决方案 > Pandas Vectorize 组合:嵌套循环、MultiIndex loc、numpy select

问题描述

我可以使用矢量化方法实现第 4 步中看到的显式 for 循环吗?

简单的数据集创建:

  1. 使用 MultiIndex 索引和相同的 MultiIndex 列声明一个 DataFrame。数据也是对称的。
import numpy as np
import pandas as pd

toy_dict={
    'a':[np.nan,3,4,-8,np.inf,np.nan,-8,9],
    'b':[3,np.nan,-3,27,-9,np.nan,9,2],
    'c':[4,-3,np.nan,3,2,-5,-7,3],
    'd':[-8,27,3,np.nan,2,1,-10,12],
    'e':[np.inf,-9,2,2,np.nan,3,7,np.nan],
    'f':[np.nan,np.nan,-5,1,3,np.nan,7,9],
    'g':[-8,9,-7,-10,7,7,np.nan,2],
    'h':[9,2,3,12,np.nan,9,2,np.nan]



}
toy_panda=pd.DataFrame.from_dict(toy_dict)

index_tuple=(
    ('a','a'),
    ('a','b'),
    ('a','c'),
    ('a','d'),
    ('b','a'),
    ('b','b'),
    ('b','c'),
    ('b','d'),
)
my_MultiIndex=pd.MultiIndex.from_tuples(index_tuple)
toy_panda.set_index(my_MultiIndex,inplace=True)
toy_panda.columns=my_MultiIndex

  1. 我声明了一个我想要子集的列表列表
list_of_indices_lists=[
    [('a','a'),('a','b')],
    [('b','c')],
    [('a','a'),('a','b'),('a','d')],
    [('b','b'),('b','c')]
]

我要矢量化的代码

  1. 我使用嵌套的 for 循环来迭代我的子集列表,在外循环的当前索引处开始内循环。
  2. 对于每个子集,我将 np.select 与标准列表一起应用
def one_df_aggregate(temp_df):
    '''
    given an numpy array, chooses what the aggregate value is
    '''
    print(temp_df)
    conditions=[
        np.isnan(temp_df).any(axis=None),
        (temp_df==np.inf).all(axis=None),
        (temp_df==-np.inf).all(axis=None),
        ((temp_df<0).any(axis=None) and (temp_df>0).any(axis=None)),
        (temp_df==0).any(axis=None),
        (temp_df>0).all(axis=None),
        (temp_df<0).all(axis=None)
    ]
    
    choices=[
        np.nan,
        np.inf,
        -np.inf,
        0,
        0,
        temp_df.values.min(),
        temp_df.values.max()
    ]
    return np.select(conditions,choices)


for i in range(len(list_of_indices_lists)):
    for j in range(i,len(list_of_indices_lists)):

        list_of_results.append(
            one_df_aggregate(
                toy_panda.loc[
                    toy_panda.index.isin(list_of_indices_lists[i]),
                    toy_panda.columns.isin(list_of_indices_lists[j])
                ]
            )
        )

结果 在示例数据集上运行这些 for 循环可以得到准确的结果

[数组(nan), 数组(0.), 数组(nan), 数组(nan), 数组(nan), 数组(0.), 数组(nan), 数组(nan), 数组(nan), 数组(南)]

但它没有矢量化,所以我知道它会很慢。

标签: pythonpandasvectorizationmulti-indexpandas-loc

解决方案


经过广泛的研究,我正在学习以“不”作为答案。原因是这个问题本质上涉及向量化屏蔽/切片,当结果具有不同维度时这是不可能的

numpy/scipy中的矢量化索引/切片?

作为一种替代策略,我想知道是否可以将已使用 loc 删除的值设置为某种我忽略的值。


推荐阅读