Issue with pd.DataFrame.apply with arguments



我想在新数据帧中为原始数据帧的每一行创建增强数据。

因此,我定义了要在应用程序中使用的增强方法,如下所示:

def augment(row: pd.Series, column_name: str, target_df: pd.DataFrame, num_samples: int):
# print(type(row))
target_df_start_index = target_df.shape[0]
raw_img = row[column_name].astype('uint8')
bin_image = convert_image_to_binary_image(raw_img)
bin_3dimg = tf.expand_dims(input=bin_image, axis=2)
bin_img_reshaped = tf.image.resize_with_pad(image=bin_3dimg, target_width=128, target_height=128, method="bilinear")
for i in range(num_samples + 1):
new_row = row.copy(deep=True)
if i == 0:
new_row[column_name] = np.squeeze(bin_img_reshaped, axis=2)
else:
aug_image = data_augmentation0(bin_img_reshaped)
new_row[column_name] = np.squeeze(aug_image, axis=2)
# display.display(new_row)
target_df.loc[target_df_start_index + i] = new_row
# print(target_df.shape)
# display.display(target_df)

当我按如下方式调用它时,一切正常:

tmp_df = pd.DataFrame(None, columns=testDF.columns)
augment(testDF.iloc[0], column_name='binMap', target_df=tmp_df, num_samples=4)
augment(testDF.iloc[1], column_name='binMap', target_df=tmp_df, num_samples=4)

但是,当我使用"apply"方法尝试时,我得到了打印或显示工作正常,但结果数据帧显示错误

tmp_df = pd.DataFrame(None, columns=testDF.columns)
testDF.apply(augment, args=('binMap', tmp_df, 4, ), axis=1)

这是应用调用后 o/p 数据的样子 -

,data
<Error>, <Error>
<Error>, <Error>

我做错了什么?

你的测试非常好,谢谢你的清晰阐述。 我很高兴成为你的橡皮鸭。

在测试 A 中,您(成功)搞砸了testDF.iloc[0][1], 使用一种 Fortran 风格的 API 对于 augment(),留下副作用会导致tmp_df。

测试 B 经过精心构造,以 除了.apply()调用外,保持"相同"。 那么让我们看看,有什么不同? 很难说。 让我们去检查文档。

哦,对了! 我们正在使用 .apply() API, 所以我们最好遵循它。 最后它解释道:

返回:系列或数据帧

沿数据帧的给定轴应用 func 的结果。

但你提供的却是return None

现在,我不是来评判的 是否有副作用最好 在目标df- 这取决于你。 但是 .apply() 会被弯曲变形 直到你给它一些好东西存储为自己的结果。 狩猎愉快!


微小的风格尼特。

你写的

args=('binMap', tmp_df, 4, )

提供 3 元组。写得更好

args=('binMap', tmp_df, 4)

正如所写,它倾向于建议 1 元组表示法。

尾随逗号什么时候有用?

  1. 在 1 元组中,它是必不可少的:x = (7,)
  2. 在多行字典/列表表达式中,它最大限度地减少了 git 差异,而稍后不可避免地会添加另一个条目("樱桃"?
fruits = [
'apple',
'banana',
]

这个变化对我有用——

def augment(row: pd.Series, column_name: str, target_df: pd.DataFrame, num_samples: int) -> pd.Series:
# print(type(row))
target_df_start_index = target_df.shape[0]
raw_img = row[column_name].astype('uint8')
bin_image = convert_image_to_binary_image(raw_img)
bin_3dimg = tf.expand_dims(input=bin_image, axis=2)
bin_img_reshaped = tf.image.resize_with_pad(image=bin_3dimg, target_width=128, target_height=128, method="bilinear")
for i in range(num_samples + 1):
new_row = row.copy(deep=True)
if i == 0:
new_row[column_name] = np.squeeze(bin_img_reshaped, axis=2)
else:
aug_image = data_augmentation0(bin_img_reshaped)
new_row[column_name] = np.squeeze(aug_image, axis=2)
# display.display(new_row)
target_df.loc[target_df_start_index + i] = new_row
# print(target_df.shape)
# display.display(target_df)
return row

并更新了调用以应用如下:

testDF = testDF.apply(augment, args=('binMap', tmp_df, 4, ), result_type='broadcast', axis=1)

谢谢@J_H。 如果有更好的方法来实现我正在做的事情,请随时提出改进建议。

最新更新