包含2d Numpy数组的pandas数据框上的Python lambda



我需要根据此规则转换几个numpy数组。获取多个数组。做元素比较。如果该位置的给定数组的值大于0.5,并且是该索引下所有数组中最大的,则对应输出数组在该位置的值为1。否则- 0。

import pandas as pd
import numpy as np
def max_is_greater_than_half_1d(*args):
df = pd.DataFrame(dict({'col_'+str(i+1): val for i, val in enumerate(args)}))
max_val = df.apply(max, axis=1)
df = df.apply(lambda x: (x > 0.5) & (max_val == x), axis=0).astype(int)
return [np.array(df[col].values) for col in df.columns]
in_1=np.array([0.4, 0.7, 0.8, 0.3, 0.3])
in_2=np.array([0.9, 0.8, 0.6, 0.4, 0.4])
in_3=np.array([0.5, 0.5, 0.5, 0.2, 0.6])
out_1, out_2, out_3 = max_is_greater_than_half(in_1, in_2,in_3)
# out_1: [0, 0, 1, 0, 0]
# out_2: [1, 1, 0, 0, 0]
# out_3: [0, 0, 0, 0, 1]

这工作。但是我怎么能对几个二维数组做同样的操作呢?

的例子:

in_1=np.array([[0.4, 0.7], [0.8, 0.3]])
in_2=np.array([[0.9, 0.8], [0.6, 0.4])

out_1 = [[0, 0], [1, 0]]out_2 = [[1, 1], [0, 0]]

在我的例子中,我有6个2000x2000数组,所以一个元素操作将会太慢。对整个数组的操作更可取。

这几乎是相同的代码,

def max_is_greater_than_half_2d(*args):
df = pd.DataFrame(dict({'col_'+str(i+1): val.flatten() for i, val in enumerate(args)}))
max_val = df.apply(max, axis=1)
df = df.apply(lambda x: (x > 0.5) & (max_val == x), axis=0).astype(int)
return [np.array(df[col].values.reshape(-1,2)) for col in df.columns]
in_1=np.array([[0.4, 0.7], 
[0.8, 0.3]])
in_2=np.array([[0.9, 0.8], 
[0.6, 0.4]])
max_is_greater_than_half_2d(in_1, in_2)

或者你可以重用一维函数

def max_is_greater_than_half_2d(*args):

args = [val.flatten() for val in args]
out  = max_is_greater_than_half_1d(*args)
return [np.array(val.reshape(-1,2)) for val in out]

这里有一个更快的比较方法:

def max_is_greater_than_half_2d_numpy(*args):
max_arr = np.maximum.reduce(args)
res = []
for ar in args:
res.append(np.where(np.logical_or(ar< max_arr, ar<0.5), 0.0, 1.0))
return res
# 0.026 s to create two arrays below
rand_1=np.random.default_rng().random((2000, 2000),dtype=np.float32)
rand_2=np.random.default_rng().random((2000, 2000),dtype=np.float32)
# 0.05 s with np.maximum.reduce, np.where
r_out_v1 = max_is_greater_than_half_2d_numpy(rand_1, rand_2)  
# 45.0 s with pandas dataframe
r_out_v2 = max_is_greater_than_half_2d_pd_df(rand_1, rand_2)  # 45.0 s

Numpynp.maximum.reduce跟随np.where的方法比pandas.dataframe的方法快1000倍,所以,我将接受我自己的答案。

最新更新