首页 > 解决方案 > 比较 Dataframe 中的每个值以创建新的 Dataframe

问题描述

试图将一个数据帧的行中的每个值与每个其他值进行比较

基于与前一行相关的行中的 if 决策

> If value1 > value2: # in row_x
>     based_on_previous_value(value1)

参考 row_x-1 然后尝试使用这些值 df_new 构建一个新的数据框

例子)

df = pandas.DataFrame({"R1": [8,2], "R2": [-21,-24], "R3": [-9,46]})
# second row in df_new for (just a  simple example of a function for clarification reasons)

def based_on_previous_value(x):
    return x*2

df_new = pandas.DataFrame({"R1": [32,2], "R2": [-21,-24], "R3": [-18,46]})

> # 8 --> 32 (because 8 ist bigger than -21 & 8 is bigger than -9) --> 8*2*2 = 32
> # -21 --> -21 (because -21 is smaller than 8 & smaller than -9) --> -21 = -21
> # -9 --> -18 (because -9 is smaller than 8 & bigger than -21) --> -9*2 = 18

编辑:示例2)

# I have a dataframe that Looks like this:
df = pandas.DataFrame({"R1": [8,2,3], "R2": [-21,-24,4], "R3": [-9,46,6],"R4": [16,-14,-1],"R5": [-3,36,76]})

如上所述:我想将一行中的每个值相互比较,然后应用一个函数(如果第 x 行中的值 1 大于第 x 行中的值 2)我正在尝试应用这样的东西:

If value1 in row1 > value2 in row 1:
    based_on_previous_value(value1) # trying to put results in a new dataframe
Else:
    return value1 # trying to put results in a new dataframe

def based_on_previous_value(x):
        x in row_before + 1

--> 此代码不起作用(只是试图显示我在代码中尝试做的事情)

# results put in a new dataframe
df_new = pandas.DataFrame({"R1": [8,10,11], "R2": [-21,-21,-19], "R3": [-9,-5,-2],"R4": [16,17,17],"R5": [-3,0,4]})

--> 第二行的“R1”:2 > -24, 2 > -14 --> 值(第一行的“R1”)+ 2 = 10 --> 第二行的“R2”:-21 < 所有其他 4 个值 --> 值(第一行中的“R2”)+ 0 = -21 --> 第二行中的“R3”:46 > 所有其他 4 个值 --> 值(第一行中的“R3”)+ 4 = -5

标签: pythonpandasdataframe

解决方案


是的,所以你需要做几件事:

看,如果您按升序排列列,最小值将出现在开头,最大值将出现在末尾。

多亏了这一点,我们可以将值乘以 2 的倍数,具体取决于它们在axis=1

所以,你的例子:

import pandas as pd
import numpy as np

df = pd.DataFrame({"R1": [8,2], "R2": [-21,-24], "R3": [-9,46]})

如果我们这样排序:

val_sorted = np.sort(df.values,axis=1)

变成:

array([[-21,  -9,   8],
       [-24,   2,  46]], dtype=int64)

接下来,我们将根据值在列轴上的位置创建乘法。

mult = [2**i for i in range(df.shape[1])]

然后我们可以将它们相乘:

sorted_mult = val_sorted*mult

输出:

array([[-21, -18,  32],
       [-24,   4, 184]], dtype=int64)

如果我们想获得数据帧的初始顺序,我们翻转值:

flipped_sorted_mult = np.fliplr(val_sorted)

输出:

array([[ 32, -18, -21],
       [184,   4, -24]], dtype=int64)

最后,我们将其放回数据框中:

df_final = pd.DataFrame(flipped_sorted_mult, columns = df.columns)

我认为这可能有点令人费解,但每个步骤都应该清楚。

现在,这是一种方法,它涉及的步骤更少,但可能更神秘:

df_sorted = df.apply(sorted,**{"reverse":True}, axis=1)
df_sorted = df_sorted.explode().values.reshape(df.shape)
df_final = pd.DataFrame(df_sorted*mult, columns=df.columns) 

发生了什么 ?

我们将内置sorted函数应用于每一行,并告诉apply方法将reverse参数作为True.

然后,我们得到一个熊猫系列,每一行都被排序,不幸的是作为一个列表。因此,我使用新的(从 pandas 0.25 开始)explode方法来分解列表,最后我将数组重新调整为初始形状。

最后一步与上述类似。

我希望它有所帮助,

干杯


推荐阅读