【发布时间】:2021-03-06 07:39:09
【问题描述】:
【问题讨论】:
-
导致最后一个df的逻辑是什么?为什么我们有两行?
-
@aprospero 第一行是有共享公共元素的列表的id,第二列是共享公共元素的元素
标签: python pandas dataframe join merge
【问题讨论】:
标签: python pandas dataframe join merge
df1 = pd.DataFrame(
{
'Id':[1,2,3],
'a':[[1,2,3],[4, 5],[6]]
},
)
df2 = pd.DataFrame(
{
'Id':[1,2,3],
'b':[[3],[6, 7],[8]]
},
)
df3 = pd.DataFrame(
{
'Id': [
[int(df1[pd.Series(map(tuple, df1['a'])) == tuple(i)].index.values)+1,
int(df1[pd.Series(map(tuple, df2['b'])) == tuple(j)].index.values)+1]
for j in df2['b'] for i in df1['a'] if set.intersection(set(i), set(j))],
'a&b': [list(set.union(set(i), set(j)))
for j in df2['b']
for i in df1['a']
if set.intersection(set(i), set(j))],
}
)
我知道我的解决方案非常混乱,但是当我尝试以其他方式解决时,例如不使用元组压缩,这很容易,然后我得到了各种错误,例如 ValueError: Lengths must match to compare,这是我们都知道的常见问题类型
【讨论】:
(df1['a'])) == i).index.values 逻辑优于 int(df1[pd.Series(map(tuple, df1['a'])) == tuple(i) 但第一个会导致很多错误和错误
set.union()获取a和b的超集
list 的组合 id 列dropna() 和你想要的列 loc[]
df = pd.DataFrame({"id":[1,2,3],
"a":[[1,2,3],[4,5],[6]]})
df1 = pd.DataFrame({"id":[1,2,3],
"b":[[3],[6,7],[8]]})
df2 = (df.assign(foo=1)
.merge(df1.assign(foo=1), on="foo")
.assign(**{"a&b":lambda dfa: np.where(dfa.apply(lambda r: any(x in r.a for x in r.b), axis=1),
dfa.apply(lambda r: list(set(r.a).union(r.b)), axis=1),
np.nan)})
.dropna()
.assign(id=lambda dfa: dfa.loc[:,["id_x","id_y"]].apply(list, axis=1))
.loc[:,["id","a&b"]]
)
| id | a&b | |
|---|---|---|
| 0 | [1, 1] | [1, 2, 3] |
| 7 | [3, 2] | [6, 7] |
list 爆炸之前复制它,以便轻松重建(df.assign(a_arr=df.a).explode("a")
.merge(df1.assign(b_arr=df1.b).explode("b"), left_on="a", right_on="b")
.assign(**{"id":lambda dfa: dfa.loc[:,["id_x","id_y"]].apply(list, axis=1),
"a&b":lambda dfa: dfa.loc[:,["a_arr","b_arr"]].apply(lambda r: list(set(r.a_arr).union(r.b_arr)), axis=1)})
.loc[:,["id","a&b"]]
)
【讨论】:
len(df) * len(df1) 行。您的 DF 中是否有任何方法可以减少可能的组合数量?