在这种情况下,有没有比 iterrows() 更有效的工具?



好的,事情是这样的。 我正在使用很多熊猫数据帧和数组。 很多时候,我需要将一帧中的值与另一帧中的值配对,理想情况下,最终将信息组合成一帧。

假设我正在查看图像文件。 每个文件都有一组特定的信息。 有时,某些类型的图像文件共享相同类型的信息。 简单的例子:

FILEPATH,    TYPE,   COLOR,   VALUE_I,<br>
/img2.jpg,    A,    'green',   0.6294<br>
/img45.jpg,   B,    'green',   0.1846<br>
/img87.jpg,   A,    'blue',    34.78<br>

通常,这些信息按类型/颜色/值等编制索引,并输入到其他一些函数中,这给了我另一个重要的输出,比如说VALUE_II。 但是我不能将其直接连接到原始数据帧上,因为索引不匹配,要么是因为输出的性质,要么是因为我只馈送了部分帧。

或者另一种情况:我了解到某个类型的图像具有特定的值,所以我制作了类型及其值的字典。 同样,此列不存在,因此在这种情况下,我将使用 iterrows(( 向下行进帧,查看类型是否与特定键匹配,以及它是否确实将其附加到数组中。 最后,我将该数组转换为数据帧并将其连接到原始数组上。

这是更糟糕的罪犯。 每帧最多 1800 行,需要很长时间。

newColumn = []
for index, row in originalDataframe.iterrows():
for indx, rw in otherDataframe.iterrows():
if row['filename'] in rw['filepath']:
newColumn.append([rw['VALUE_I'],rw['VALUE_II'], rw['VALUE_III']])
newColumn = pd.DataFrame(newColumn, columns = ['VALUE_I', 'VALUE_II', 'VALUE_III'])
originalDataframe = pd.concat([originalDataframe, newColumn], axis=1)

解决方案将不胜感激!

如果您可以将文件名与otherDataframe["filepath"]拆分,那么您可以只比较与 orinalDataframe 的文件名相等,而无需检查in。之后,您可以使用熊猫简化计算。DataFrame.join,对于原始数据帧中的每个文件名,它将在其他数据帧中找到相同的文件名,并从中添加所有其他列。

import os
otherDataframe["filename"] = otherDataframe["filepath"].map(os.path.basename)
joinedDataframe = originalDataframe.join(otherDataframe.set_index("filename"), on="filename")

如果原始数据帧和其他数据帧中存在同名的列,则应设置 l后缀或后缀。

专注于问题的后半部分,因为这是您提供代码的内容。 程序正在对照 df2 中的每一行检查 df1 的每一行,从而产生可能 1800 *1800 或 3240000 种可能的组合。 如果每行只有一个可能的匹配项,那么添加"break"将有所帮助,但并不理想。 newColumn.append([rw['VALUE_I'],rw['VALUE_II'], rw['VALUE_III']]) break

如果你的数据结构允许,我会尝试这样的东西:

ref = {}
for i, path in enumerate(otherDataframe['filepath']):
*_, file = path.split('\')
ref[file] = i
originalDataframe['VALUE_I'] = None
originalDataframe['VALUE_II'] = None
originalDataframe['VALUE_III'] = None
for i, file in enumerate(originalDataframe['filename']):
try:
j = ref[file]
originalDataframe.loc[i, 'VALUE_I'] = otherDataframe.loc[j, 'VALUE_I']
originalDataframe.loc[i, 'VALUE_II'] = otherDataframe.loc[j, 'VALUE_II']
originalDataframe.loc[i, 'VALUE_III'] = otherDataframe.loc[j, 'VALUE_III']
except:
pass

在这里,我们遍历 otherDataframe 中的路径(我假设它们遵循 C:\asdf\asdf\file 的模式(,拆分 \ 上的路径以提取文件,然后构造一个文件字典到行号。 接下来,我们初始化原始数据帧中要写入的 3 列。

最后,我们遍历原始数据帧中的文件,检查该文件是否存在于其他数据帧中的文件字典中(在尝试捕获错误时完成(,然后提取行号(从字典中取出(,然后我们用它来将值从其他写入原始值。

旁注,您将路径描述为"C:/asd/fdg/img2.jpg"的脉络,在这种情况下,您应该使用:

*_, file = path.split('/')

相关内容

最新更新