使用应用功能在 Dask 中添加两列
Adding two columns in Dask with apply function
我有一个 Dask 函数,可以将一列添加到现有的 Dask 数据框,这很好用:
df = pd.DataFrame({
'height': [6.21, 5.12, 5.85, 5.78, 5.98],
'weight': [150, 126, 133, 164, 203]
})
df_dask = dd.from_pandas(df, npartitions=2)
s = """
obj.weight + 100
"""
df_dask['new_weight'] = df_dask.apply(lambda obj: eval(s), meta=dict, axis=1)
现在,我想添加两列而不是一列:
s = """
obj.weight + 100, obj.weight + 200
"""
df_dask['new_weight','new_weight2'] = df_dask.apply(lambda obj: eval(s), meta=dict, axis=1)
但是我明白了
NotImplementedError: Item assignment with <class 'tuple'> not supported
这是否意味着不支持或我做错了什么?如果不支持,是否有解决方法?我需要的是 return 一个浮动列表。
首先,确保基于 pandas
的解决方案提供预期结果将很有用:
df = pd.DataFrame({
'height': [6.21, 5.12, 5.85, 5.78, 5.98],
'weight': [150, 126, 133, 164, 203]
})
s = """
obj.weight + 100, obj.weight + 200
"""
df['new_weight'], df['new_weight2'] = zip(*df.apply(lambda obj: eval(s), axis=1))
print(df)
# height weight new_weight new_weight2
# 0 6.21 150 250.0 350.0
# 1 5.12 126 226.0 326.0
# 2 5.85 133 233.0 333.0
# 3 5.78 164 264.0 364.0
# 4 5.98 203 303.0 403.0
现在,dask
解决方案。由于每个分区都是一个 pandas
数据帧,最简单的解决方案(对于基于行的转换)是将 pandas
代码包装到一个函数中并将其插入 map_partitions
:
df = pd.DataFrame({
'height': [6.21, 5.12, 5.85, 5.78, 5.98],
'weight': [150, 126, 133, 164, 203]
})
s = """
obj.weight + 100, obj.weight + 200
"""
df_dask = dd.from_pandas(df, npartitions=2)
def new_cols(df):
df = df.copy()
df['new_weight'], df['new_weight2'] = zip(*df.apply(lambda obj: eval(s), axis=1))
return df
df_dask = df_dask.map_partitions(new_cols)
print(df_dask.compute())
# height weight new_weight new_weight2
# 0 6.21 150 250.0 350.0
# 1 5.12 126 226.0 326.0
# 2 5.85 133 233.0 333.0
# 3 5.78 164 264.0 364.0
# 4 5.98 203 303.0 403.0
根据您的用例的具体情况,上述模式可能具有提高效率的空间。
我有一个 Dask 函数,可以将一列添加到现有的 Dask 数据框,这很好用:
df = pd.DataFrame({
'height': [6.21, 5.12, 5.85, 5.78, 5.98],
'weight': [150, 126, 133, 164, 203]
})
df_dask = dd.from_pandas(df, npartitions=2)
s = """
obj.weight + 100
"""
df_dask['new_weight'] = df_dask.apply(lambda obj: eval(s), meta=dict, axis=1)
现在,我想添加两列而不是一列:
s = """
obj.weight + 100, obj.weight + 200
"""
df_dask['new_weight','new_weight2'] = df_dask.apply(lambda obj: eval(s), meta=dict, axis=1)
但是我明白了
NotImplementedError: Item assignment with <class 'tuple'> not supported
这是否意味着不支持或我做错了什么?如果不支持,是否有解决方法?我需要的是 return 一个浮动列表。
首先,确保基于 pandas
的解决方案提供预期结果将很有用:
df = pd.DataFrame({
'height': [6.21, 5.12, 5.85, 5.78, 5.98],
'weight': [150, 126, 133, 164, 203]
})
s = """
obj.weight + 100, obj.weight + 200
"""
df['new_weight'], df['new_weight2'] = zip(*df.apply(lambda obj: eval(s), axis=1))
print(df)
# height weight new_weight new_weight2
# 0 6.21 150 250.0 350.0
# 1 5.12 126 226.0 326.0
# 2 5.85 133 233.0 333.0
# 3 5.78 164 264.0 364.0
# 4 5.98 203 303.0 403.0
现在,dask
解决方案。由于每个分区都是一个 pandas
数据帧,最简单的解决方案(对于基于行的转换)是将 pandas
代码包装到一个函数中并将其插入 map_partitions
:
df = pd.DataFrame({
'height': [6.21, 5.12, 5.85, 5.78, 5.98],
'weight': [150, 126, 133, 164, 203]
})
s = """
obj.weight + 100, obj.weight + 200
"""
df_dask = dd.from_pandas(df, npartitions=2)
def new_cols(df):
df = df.copy()
df['new_weight'], df['new_weight2'] = zip(*df.apply(lambda obj: eval(s), axis=1))
return df
df_dask = df_dask.map_partitions(new_cols)
print(df_dask.compute())
# height weight new_weight new_weight2
# 0 6.21 150 250.0 350.0
# 1 5.12 126 226.0 326.0
# 2 5.85 133 233.0 333.0
# 3 5.78 164 264.0 364.0
# 4 5.98 203 303.0 403.0
根据您的用例的具体情况,上述模式可能具有提高效率的空间。