python - 在多行 DataFrame 上应用自定义函数
问题描述
我目前正在开发一个函数,该函数将根据多个条件(平方米、图像和价格)检测行是否重复。它工作得很好,直到找到重复项,从 DataFrame 中删除该行,然后我的 for 循环受到干扰。这产生IndexError: single positional indexer is out-of-bounds
.
def image_duplicate(df):
# Detecting duplicates based on the publications' images, m2 and price.
for index1 in df.index:
for index2 in df.index:
if index1 == index2:
continue
print('index1: {} \t index2: {}'.format(index1, index2))
img1 = Image.open(requests.get(df['img_url'].iloc[index1], stream=True).raw).resize((213, 160))
img2 = Image.open(requests.get(df['img_url'].iloc[index2], stream=True).raw).resize((213, 160))
img1 = np.array(img1).astype(float)
img2 = np.array(img2).astype(float)
ssim_result = ssim(img1, img2, multichannel=True)
ssim_result_percentage = (1+ssim_result)/2
if ssim_result_percentage > 0.80 and df['m2'].iloc[index1] == df['m2'].iloc[index2] \
and df['Price'].iloc[index1] == df['Price'].iloc[index2]:
df.drop(df.iloc[index2], inplace=True).reindex()
image_duplicate(full_df)
什么是解决这个问题的好方法?
预期输出:从 DataFrame 中删除 One Bedroom 行 [2]。
解决方案
从您的问题看来(如果我错了,请纠正我)您需要迭代索引(笛卡尔积)并index2
从原始数据框中删除第二个索引(在您的示例中)。
我会推荐这样的东西来解决你的问题:
import itertools
def image_duplicate(df):
# Detecting duplicates based on the publications' images, m2 and price.
indexes_to_drop = []
for index1, index2 in itertools.product(df.index, df.index):
if index1 == index2:
continue
print("index1: {} \t index2: {}".format(index1, index2))
img1 = Image.open(requests.get(df["img_url"].iloc[index1], stream=True).raw).resize((213, 160))
img2 = Image.open(requests.get(df["img_url"].iloc[index2], stream=True).raw).resize((213, 160))
img1 = np.array(img1).astype(float)
img2 = np.array(img2).astype(float)
ssim_result = ssim(img1, img2, multichannel=True)
ssim_result_percentage = (1 + ssim_result) / 2
if (
ssim_result_percentage > 0.80
and df["m2"].iloc[index1] == df["m2"].iloc[index2]
and df["Price"].iloc[index1] == df["Price"].iloc[index2]
):
indexes_to_drop.append(index2)
indexes_to_drop = list(set(indexes_to_drop))
return df.drop(indexes_to_remove)
output_df = image_duplicate(full_df) # `output_df` should contain the expected output
解释:
- 遍历索引(在这种情况下,我更喜欢使用 itertools,但可以随意将您的方法与 for 循环一起使用)
- 创建
indexes_to_drop
列表,而不是放在最后,将这些索引附加到列表中 - 获取要删除的唯一索引列表(可能会发生相同的索引将在列表中出现重复时间) -
list(set(indexes_to_drop))
是如何删除重复项的简单方法(集合不能包含重复项) - 立即删除这些索引(不确定您为什么
.reindex
在示例中使用)
可能还有其他方法可以改进您的代码,例如,不要比较列表index2
中已经存在的图像indexes_to_drop
(例如,如果为 True,则检查if index2 in indexes_to_drop
并继续),或者您甚至可以将其转换为可以使用的函数apply
(迭代index2
将在 apply 内部发生) ),但这不是必需的。
推荐阅读
- java - 如何在不使用 INSERT INTO SELECT 语句的情况下实现该程序以导入表?
- php - Python中PHP对象的相同哈希
- laravel - 无法使用 2 个可能的身份验证器在用户名“yea****”的 SMTP 服务器上进行身份验证
- webpack - 将所有css提取到一个文件中的目的是什么
- angular - 在组件类中调用服务构造函数
- php - Woocommerce - 更改快速查看按钮文本和眼睛图标
- node.js - 将 HTML 按钮链接到 node.js 帖子
- angular - 为什么我的代码在 ANGULAR 5 中出现名称属性错误?
- python - 'GroupedData' 对象在 spark 数据帧中执行枢轴时没有属性'show'
- sql - Microsoft Access 数据库引擎在运行更新查询时找不到对象“错误