цепочка объединяет несколько аргументов из списка переменного размера, используя поставляемую двумерную функцию - PullRequest
0 голосов
/ 10 июня 2019

Я хочу выполнить функцию над всеми аргументами в списке (map может выполнить эту часть), а затем «соединить» их, используя другую функцию, которую можно было закрыть раньше (например, если целью было найти экземпляр или достичь порога).

Вот пример, где функция ~np.isnan над переменным числом столбцов из фрейма данных, а "join" - это побитовый оператор & в результирующих логических масках. Таким образом он находит, есть ли какие-либо значения NaN во фрейме данных, где местоположение соответствует переменному списку столбцов. Затем я удаляю строки, в которых для указанных имен столбцов найден NaN.

import pandas as pd
import numpy as np
import random

data_values = range(10)
column_names = list(map(lambda x: "C" + str(x), data_values))
data = pd.DataFrame(columns=column_names, data=np.reshape(np.repeat(data_values,10,0),(10,10)))
data.iloc[random.sample(data_values,random.sample(data_values,1)[0]),random.sample(data_values,random.sample(data_values,1)[0])] = np.nan
cols_to_check = random.sample(column_names,random.sample(data_values,1)[0])
# ideally: data.loc[pd.notnull(data[cols_to_check[0]]) & pd.notnull(data[cols_to_check[1]]) & ...]
# or perhaps: data.loc[chainFunc(pd.notnull, np.logical_and, cols_to_check)]
masks = [list(np.where(~np.isnan(data[x]))[0]) for x in cols_to_check]
data.iloc[list(set(masks[0]).intersection(*masks))]

Это становится очень медленным для больших фреймов данных, но возможно ли обобщить это с помощью itertools и functools и кардинально улучшить производительность? Скажите что-то вроде ( псевдокод ):

def chainFunc(func_applied, func_chain, args):
    x = func_applied(args[0])
    for arg_counter in range(len(args)-1):
        x = func_chain(x,func_applied(args[arg_counter+1]))
    return(x)

Как это будет работать на приведенном выше примере с фреймом данных?

1 Ответ

0 голосов
/ 23 июня 2019

Я искал общий способ объединить произвольный список аргументов и применить результат к фрейму данных.Я предполагаю, что в приведенном выше примере приложение близко к dropNA, но не совсем.Я искал комбинацию reduce и chain, нет реального pandas конкретного интерфейса этого, но можно получить что-то работающее:

import functools
data.iloc[ np.where(functools.reduce(lambda x, y: x & y, 
                                     map(lambda z: pd.notnull(data[z]), 
                                         cols_to_check)))[0] ]
...