假设我们有一个pandas数据帧df,其列为'A',以及下面的非向量化转换函数:

def transform_a_to_b(a):
    ...
    return b

然后,如果我们想要使用'A'上的转换创建列'B',我们可以执行以下操作:

df['B'] = df['A'].apply(lambda x: transform_a_to_b(a))

如果转换花费的时间不是很多,列'A'中有许多重复的值,并且转换总是将重复的a值映射到相同的b值,那么执行此操作的更好方式是什么?另外,假设数据框中有更多列,因此我确实希望将这些值映射回原始数据框中的每一行.

我想出了下面的解决方案,但我觉得应该有更简单的东西.

transform_counts = 0
def transform_a_to_b(a):
    global transform_counts
    # Keep count of how many times this was called
    transform_counts += 1

    return 2 * a

# Test dataframe with several duplicates
df = pd.DataFrame({
    'A': [1, 3, 2, 2, 3, 3, 2, 3, 1, 1, 1],
})

# My solution:
# Perform transformation only 3 times for the 3 unique A values and preserve order
df = df.merge(
    df['A'].drop_duplicates().apply(lambda a: pd.Series(
        data=[a, transform_a_to_b(a)],
        index=['A', 'B'],
    )),
    on='A',
    how='left',
)

函数transform_counts3且df如下所示:

    A  B
0   1  2
1   3  6
2   2  4
3   2  4
4   3  6
5   3  6
6   2  4
7   3  6
8   1  2
9   1  2
10  1  2

我不反对缓存,如果这是最简单的,但我不能更改原始的转换定义.

推荐答案

你的方法很好,我会用map + unique代替merge + drop_duplicates.

df['B'] = df['A'].map({k: transform_a_to_b(k) for k in df['A'].unique()})

一种毒蛇般的替代方案将是.cache您的功能:

from functools import cache

transform_counts = 0

@cache
def transform_a_to_b(a):
    global transform_counts
    # Keep count of how many times this was called
    transform_counts += 1
    return 2 * a

df = pd.DataFrame({
    'A': [1, 3, 2, 2, 3, 3, 2, 3, 1, 1, 1],
})

df['B'] = df['A'].map(transform_a_to_b)

print(df)

输出:

    A  B
0   1  2
1   3  6
2   2  4
3   2  4
4   3  6
5   3  6
6   2  4
7   3  6
8   1  2
9   1  2
10  1  2

Python相关问答推荐

比较两个数据帧并并排附加结果(获取性能警告)

滚动和,句号来自Pandas列

Django mysql图标不适用于小 case

重新匹配{ }中包含的文本,其中文本可能包含{{var}

运行终端命令时出现问题:pip start anonymous"

聚合具有重复元素的Python字典列表,并添加具有重复元素数量的新键

如何让程序打印新段落上的每一行?

C#使用程序从Python中执行Exec文件

如何在Python中并行化以下搜索?

在vscode上使用Python虚拟环境时((env))

Pandas—在数据透视表中占总数的百分比

启用/禁用shiny 的自动重新加载

基于多个数组的多个条件将值添加到numpy数组

如何在海上配对图中使某些标记周围的黑色边框

删除特定列后的所有列

没有内置pip模块的Python3.11--S在做什么?

从列表中分离数据的最佳方式

Matplotlib中的曲线箭头样式

多索引数据帧到标准索引DF

try 使用RegEx解析由标识多行文本数据的3行头组成的日志(log)文件