首页 > 解决方案 > 将函数应用于数据框中的每两列并用输出替换原始列

问题描述

我有一个数据框,其中包含这样的列中的 X 和 Y 数据:

df_cols = ['x1', 'y1', 'x2', 'y2', 'x3', 'y3']

np.random.seed(365)
df = pd.DataFrame(np.random.randint(0,10,size=(10, 6)), columns=df_cols)

   x1  y1  x2  y2  x3  y3
0   2   4   1   5   2   2
1   9   8   4   0   3   3
2   7   7   7   0   8   4
3   3   2   6   2   6   8
4   9   6   1   6   5   7
5   7   6   5   9   3   8
6   7   9   9   0   1   4
7   0   9   6   5   6   9
8   5   3   2   7   9   2
9   6   6   3   7   7   1

我需要调用一个函数,该函数一次获取一个 X 和 Y 对并返回并更新 X 和 Y 对(相同长度),然后将该数据保存到具有原始列名的新数据帧中,或者替换旧的 X &Y 数据用新数据并保留原来的列名。

例如,下面这个函数:

def samplefunc(x, y):
    x = x*y
    y = x/10
    return x, y

# Apply function to each x & y pair 
x1, y1 = samplefunc(df.x1, df.y1)
x2, y2 = samplefunc(df.x2, df.y2)
x3, y3 = samplefunc(df.x3, df.y3)

 # Save new/updated x & y pairs into new dataframe, preserving the original column names 
df_updated = pd.DataFrame({'x1': x1, 'y1': y1, 'x2': x2, 'y2': y2, 'x3': x3, 'y3': y3})

# Desired result:
In [36]: df_updated
Out[36]: 
   x1   y1  x2   y2  x3   y3
0   8  0.8   5  0.5   4  0.4
1  72  7.2   0  0.0   9  0.9
2  49  4.9   0  0.0  32  3.2
3   6  0.6  12  1.2  48  4.8
4  54  5.4   6  0.6  35  3.5
5  42  4.2  45  4.5  24  2.4
6  63  6.3   0  0.0   4  0.4
7   0  0.0  30  3.0  54  5.4
8  15  1.5  14  1.4  18  1.8
9  36  3.6  21  2.1   7  0.7

但是对于一个庞大的数据集来说,这样做显然是非常乏味和不可能的。我发现的类似/相关问题对数据执行简单的转换而不是调用函数,或者它们向数据框添加新列而不是替换原始列。

我试图将@PaulH 的答案应用于我的数据集,但它们都没有工作,因为不清楚如何在这两种方法中实际调用函数。

# Method 1
array = np.array(my_actual_df)
df_cols = my_actual_df.columns
dist = 0.04 # a parameter I need for my function 
df = (
    pandas.DataFrame(array, columns=df_cols)
        .rename_axis(index='idx', columns='label')
        .stack()
        .to_frame('value')
        .reset_index()
        .assign(value=lambda df: numpy.select(
            [df['label'].str.startswith('x'), df['label'].str.startswith('y')],

            # Call the function (not working): 
            [df['value'], df['value']] = samplefunc(df['value'], df['value']),
        ))
        .pivot(index='idx', columns='label', values='value')
        .loc[:, df_cols]
)



# Method 2
df = (
    pandas.DataFrame(array, columns=df_cols)
        .pipe(lambda df: df.set_axis(df.columns.map(lambda c: (c[0], c[1])), axis='columns'))
        .rename_axis(columns=['which', 'group'])
        .stack(level='group')
         
        # Call the function (not working)
        .assign(df['x'], df['y'] = samplefunc(df['x'], df['y']))
        .unstack(level='group')
        .pipe(lambda df: df.set_axis([''.join(c) for c in df.columns], axis='columns'))
)

我需要调用的实际函数来自 Arty 对这个问题的回答:重新 采样轨迹以在每个样本中具有相等的欧几里得距离

标签: pythonpandasdataframenumpy

解决方案


使用切片并对这些切片应用操作。

def samplefunc(x, y):
    x = x**2
    y = y/10
    return x, y

arr = df.to_numpy().astype(object) 
e_col = arr[:, ::2]
o_col =  arr[:, 1::2]
e_col, o_col = samplefunc(e_col, o_col)
arr[:, ::2] = e_col 
arr[:, 1::2] = o_col 
out = pd.DataFrame(arr, columns=df.columns)

   x1   y1  x2   y2  x3   y3
0   4  0.4   1  0.5   4  0.2
1  81  0.8  16  0.0   9  0.3
2  49  0.7  49  0.0  64  0.4
3   9  0.2  36  0.2  36  0.8
4  81  0.6   1  0.6  25  0.7
5  49  0.6  25  0.9   9  0.8
6  49  0.9  81  0.0   1  0.4
7   0  0.9  36  0.5  36  0.9
8  25  0.3   4  0.7  81  0.2
9  36  0.6   9  0.7  49  0.1

推荐阅读