[英]Creating a Pandas DataFrame from a Numpy array: How do I specify the index column and column headers?
[英]How do I get the index pairs from an inner join using pandas without creating the resulting dataframe?
我想合并两个数据框,但不是返回完整连接,而是返回显示成对行的两列。
我在下面编写了一个示例 function,但它创建了两个数据帧的内部连接,包括所有不需要的列。 如果有很多列和行,这个可以使用很多memory。
def get_index_pairs(df1, df2, on):
return pd.merge(df1.reset_index(), df2.reset_index(), on=on)[['index_x', 'index_y']]
df1 = pd.DataFrame( dict( key = ["a","b","c","d"], v1=[1,2,3,4]))
df2 = pd.DataFrame( dict( key = ["b","d","f","g"], v2=[10,20,30,40]))
pairs = get_index_pairs(df1, df2, on='key')
print(pairs)
index_x index_y
0 1 0
1 3 1
我正在寻找更 memory 高效版本的get_index_pairs
。
数据
出于演示目的,对数据进行了微调。 具体来说, key="d"
将有一个2*2
笛卡尔连接。
import pandas as pd
import numpy as np
df1 = pd.DataFrame( dict( key = ["a","b","d","d"], v1=[1,2,3,4]))
df2 = pd.DataFrame( dict( key = ["b","d","d","g"], v2=[10,20,30,40]))
代码
使用np.argwhere()
返回所有匹配的索引。
ls = []
for i1, k1 in enumerate(df1["key"]): # the only slow step (explicit for loop)
for i2 in np.argwhere((df2["key"] == k1).values):
ls.append([i1, i2[0]])
df_ans = pd.DataFrame(ls, columns=["index_x", "index_y"])
结果
print(df_ans)
index_x index_y
0 1 0
1 2 1 <- Cartesian join on "d" like what
2 2 2 <- would be produced by an
3 3 1 <- inner join
4 3 2 <-
笔记
OP 要求减少 memory 的使用,而不是更快的执行。 否则pd.merge()
在速度方面将是首选。
为您的搜索构造包含{key: index}
对的dict
。 在搜索过程中,只会消耗dfN["key"]
大小的恒定倍数。
代码
# {key: index} mappings
dic1 = dict(zip(df1["key"].values, range(len(df1))))
dic2 = dict(zip(df2["key"].values, range(len(df2))))
# collect matched results
ls = []
for k1, v1 in dic1.items(): # the only slow step (explicit for loop)
if k1 in dic2: # fast (hashed search)
ls.append([v1, dic2[k1]])
df_ans = pd.DataFrame(ls, columns=["index_x", "index_y"])
结果
print(df_ans)
index_x index_y
0 1 0
1 3 1
另一种选择是使用 pandas DataFrame align
,以对齐key
上的轴:
def get_index_pairs(df1, df2, on):
left, right = pd.DataFrame.align(
df1.set_index(on), df2.set_index(on), axis="index", join="inner"
)
left_index = df1.index[df1.loc[:, on].isin(left.index)]
right_index = df2.index[df2.loc[:, on].isin(right.index)]
return pd.DataFrame({"index_x": left_index, "index_y": right_index})
df1 = pd.DataFrame(dict(key=["a", "b", "c", "d"], v1=[1, 2, 3, 4]))
df2 = pd.DataFrame(dict(key=["b", "d", "f", "g"], v2=[10, 20, 30, 40]))
pairs = get_index_pairs(df1, df2, on="key")
print(pairs)
index_x index_y
0 1 0
1 3 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.