【问题标题】:Pandas .loc to find certain index values taking too long. Any alternatives to my method?Pandas .loc 查找某些索引值花费的时间太长。我的方法有什么替代方法吗?
【发布时间】:2019-05-26 00:07:27
【问题描述】:

我目前正在尝试查找包含至少一个键值列表的 csv 的所有行。这是我目前的方法:

name_index = []
basics = pd.read_csv('name.basics.csv')
basics_unprocessed = pd.read_csv('name.basics.csv')
for i,ID in enumerate(movie_title_ids):
    ind = tuple(basics_unprocessed.loc[basics_unprocessed['knownForTitles'].str.contains(ID)].index)
    name_index.extend(ind)
    try:
        basics_unprocessed.drop(ind[0], inplace=True)
    except:
        print('drop failed')
    if i%100 == 0:
        print(i)

这里的想法是name_index 列表将包含所有索引,这些索引至少包含一个指定的 ID 键值。

理想情况下,这段代码可以满足我的需要,但它会花费很长时间,因为 ID 列表的大小为数千,而 csv 文件有几百万行。我并没有真正使用大数据工具,但如果它对我有帮助,我愿意学习一些东西。关于使我的代码更高效或其他工具的任何建议(我的朋友建议使用 spark 或其他工具可能会有所帮助)

【问题讨论】:

标签: python-3.x pandas


【解决方案1】:

你可以vectorize这整个操作。首先,无需进行多个查找并一次完成所有查找,使用regular expression 加入它们,其中多个选项(或)与| 重复。请注意,我假设这些电影标题 ID 不包含特殊字符,如果是这样,您将需要转义它们。我相信即使有几千个选项,这也会快得多。

mask = basics.knownForTitles.str.contains('|'.join(movie_title_ids))

然后,您可以过滤掉所有符合条件的行,因为这会返回一个您可以索引的mask

basics = basics[~mask]


此外,您的代码已经有很多冗余操作,无论迭代地执行此操作,它们都会减慢速度。
for i,ID in enumerate(movie_title_ids):
    ind = tuple(basics_unprocessed.loc[basics_unprocessed['knownForTitles'].str.contains(ID)].index)

这里不需要找到所有这些项目的索引,因为您会得到一个可以立即删除的掩码。

    name_index.extend(ind)
    try:
        basics_unprocessed.drop(ind[0], inplace=True)
    except:
        print('drop failed')

您每次都执行所有收集到的物品的掉落。当第一次下降的索引不存在时会发生什么?

【讨论】:

  • 谢谢!这对我有用。在我为另一个函数执行的代码中考虑到前面的操作,我没有对操作进行矢量化,这是一个特别愚蠢的错误。
  • @MadhuM。很高兴听到它对您有用,请您接受答案。
猜你喜欢
  • 2011-12-06
  • 1970-01-01
  • 1970-01-01
  • 2014-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-24
  • 1970-01-01
相关资源
最近更新 更多