对于python Pandas/numpy,R的match()相当于什么?

Sol*_*mon 6 python merge r match pandas

我是一个R用户,我无法弄清楚匹配的匹配()的熊猫.我需要使用这个函数迭代一堆文件,获取一个关键信息,然后将它合并回'url'上的当前数据结构.在R我会做这样的事情:

logActions <- read.csv("data/logactions.csv")
logActions$class <- NA

files = dir("data/textContentClassified/")
for( i in 1:length(files)){
    tmp <- read.csv(files[i])
    logActions$class[match(logActions$url, tmp$url)] <- 
            tmp$class[match(tmp$url, logActions$url)]
}
Run Code Online (Sandbox Code Playgroud)

我不认为我可以使用merge()或join(),因为每次都会覆盖logActions $ class.我也不能使用update()或combine_first(),因为它们都没有必要的索引功能.我也试过基于这个SO帖子创建一个match()函数,但是无法弄清楚如何让它与DataFrame对象一起工作.如果我遗漏了一些明显的东西,请道歉.

这里有一些python代码总结了我在pandas中执行类似match()的无效尝试:

from pandas import *
left = DataFrame({'url': ['foo.com', 'foo.com', 'bar.com'], 'action': [0, 1, 0]})
left["class"] = NaN
right1 = DataFrame({'url': ['foo.com'], 'class': [0]})
right2 = DataFrame({'url': ['bar.com'], 'class': [ 1]})

# Doesn't work:
left.join(right1, on='url')
merge(left, right, on='url')

# Also doesn't work the way I need it to:
left = left.combine_first(right1)
left = left.combine_first(right2)
left 

# Also does something funky and doesn't really work the way match() does:
left = left.set_index('url', drop=False)
right1 = right1.set_index('url', drop=False)
right2 = right2.set_index('url', drop=False)

left = left.combine_first(right1)
left = left.combine_first(right2)
left
Run Code Online (Sandbox Code Playgroud)

所需的输出是:

    url  action  class
0   foo.com  0   0
1   foo.com  1   0
2   bar.com  0   1
Run Code Online (Sandbox Code Playgroud)

但是,我需要能够一遍又一遍地调用它,以便我可以迭代每个文件.

Wes*_*ney 9

请注意,pandas.matchR的存在恰恰与R的match作用完全相同.


HYR*_*YRY 1

编辑

如果所有右侧数据帧中的 url 都是唯一的,则可以将右侧数据帧作为一系列索引classurl然后通过索引它可以获取左侧每个 url 的类。

from pandas import *
left = DataFrame({'url': ['foo.com', 'bar.com', 'foo.com', 'tmp', 'foo.com'], 'action': [0, 1, 0, 2, 4]})
left["klass"] = NaN
right1 = DataFrame({'url': ['foo.com', 'tmp'], 'klass': [10, 20]})
right2 = DataFrame({'url': ['bar.com'], 'klass': [30]})

left["klass"] = left.klass.combine_first(right1.set_index('url').klass[left.url].reset_index(drop=True))
left["klass"] = left.klass.combine_first(right2.set_index('url').klass[left.url].reset_index(drop=True))

print left
Run Code Online (Sandbox Code Playgroud)

这是你想要的吗?

import pandas as pd
left = pd.DataFrame({'url': ['foo.com', 'foo.com', 'bar.com'], 'action': [0, 1, 0]})
left["class"] = NaN
right1 = pd.DataFrame({'url': ['foo.com'], 'class': [0]})
right2 = pd.DataFrame({'url': ['bar.com'], 'class': [ 1]})

pd.merge(left.drop("class", axis=1), pd.concat([right1, right2]), on="url")
Run Code Online (Sandbox Code Playgroud)

输出:

   action      url  class
0       0  foo.com      0
1       1  foo.com      0
2       0  bar.com      1
Run Code Online (Sandbox Code Playgroud)

如果左侧的类列不全是 NaN,您可以将其与结果合并。