[英]Join two Pandas dataframes, sampling from the smaller dataframe
我有两个数据框,如下所示:
import pandas as pd
import io
train_data="""input_example,user_id
example0.npy, jane
example1.npy, bob
example4.npy, alice
example5.npy, jane
example3.npy, bob
example2.npy, bob
"""
user_data="""user_data,user_id
data_jane0.npy, jane
data_jane1.npy, jane
data_bob0.npy, bob
data_bob1.npy, bob
data_alice0.npy, alice
data_alice1.npy, alice
data_alice2.npy, alice
"""
train_df = pd.read_csv(io.StringIO(train_data), sep=",")
user_df = pd.read_csv(io.StringIO(user_data), sep=",")
假设train_df
表有数千个条目,即有 1000 个唯一的“exampleN.npy”文件。 我想知道是否有一种直接的方法来合并train_df
和user_df
表,其中连接表的每一行都与键user_id
匹配,但从user_df
进行子采样。
这是生成的 dataframe 的一个示例(我正在尝试进行统一采样,因此理论上,有无限可能的结果数据帧):
>>> result_df
input_example user_data user_id
0 example0.npy data_jane0.npy jane
1 example1.npy data_bob1.npy bob
2 example4.npy data_alice0.npy alice
3 example5.npy data_jane1.npy jane
4 example3.npy data_bob0.npy bob
5 example2.npy data_bob0.npy bob
也就是说, user_data
列填充了基于相应user_id
的随机选择的文件名。
我知道可以使用一些基于多行 for 循环查询的方法编写此代码,但也许有一种更快的方法使用内置 Pandas 函数,例如“sample”、“merge”、“join”或“combine” ”。
您可以在user_df
中按组进行采样,然后将其与train_df
一起加入。 例如,
# this samples by fraction so each data is equally likely
user_df = user_df.groupby("user_id").sample(frac=0.5, replace=True)
user_data user_id
6 data_alice2.npy alice
4 data_alice0.npy alice
3 data_bob1.npy bob
0 data_jane0.npy jane
或者
# this will sample 2 samples per group
user_df = user_df.groupby("user_id").sample(n=2, replace=True)
user_data user_id
6 data_alice2.npy alice
4 data_alice0.npy alice
2 data_bob0.npy bob
2 data_bob0.npy bob
0 data_jane0.npy jane
1 data_jane1.npy jane
加入
pd.merge(train_df, user_df)
我不知道是否可以在不先合并两者的情况下与样本合并。 这不包括多行 for 循环:
merged = train_df.merge(user_df, on="user_id", how="left").\
groupby("input_example", as_index=False).\
apply(lambda x: x.sample(1)).\
reset_index(drop=True)
合并后的第二个采样意味着具有相同 user_id 的行不一定相同(但首先采样 user_df 会导致 output dataframe 中的所有行都具有相同的 user_id)。
认为我自己想出了一个解决方案,它是单行的,但从概念上讲它与@Rawson 建议的相同。 首先,我进行了左合并,这会产生一个包含许多重复项的表。 然后我将所有行打乱以使其具有随机性。 最后,我删除了重复项。 如果我添加“sort_index”,结果表将与原始表具有相同的顺序。
我可以使用random_state
kwarg 来切换使用哪个 user_data 文件。 看这里:
>>> train_df.merge(user_df, on='user_id', how='left').sample(frac=1, random_state=0).drop_duplicates('input_example').sort_index()
input_example user_id user_data
1 example0.npy jane data_jane1.npy
2 example1.npy bob data_bob0.npy
6 example4.npy alice data_alice2.npy
8 example5.npy jane data_jane1.npy
10 example3.npy bob data_bob1.npy
11 example2.npy bob data_bob0.npy
>>> train_df.merge(user_df, on='user_id', how='left').sample(frac=1, random_state=1).drop_duplicates('input_example').sort_index()
input_example user_id user_data
1 example0.npy jane data_jane1.npy
2 example1.npy bob data_bob0.npy
4 example4.npy alice data_alice0.npy
7 example5.npy jane data_jane0.npy
10 example3.npy bob data_bob1.npy
12 example2.npy bob data_bob1.npy
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.