programing

두 Panda 데이터 프레임에서 공통 행 찾기(교차로)

css3 2023. 10. 27. 22:06

두 Panda 데이터 프레임에서 공통 행 찾기(교차로)

이 형식의 데이터 프레임이 두 개 있다고 가정합니다.df1그리고.df2):

+------------------------+------------------------+--------+
|        user_id         |      business_id       | rating |
+------------------------+------------------------+--------+
| rLtl8ZkDX5vH5nAx9C3q5Q | eIxSLxzIlfExI6vgAbn2JA |      4 |
| C6IOtaaYdLIT5fWd7ZYIuA | eIxSLxzIlfExI6vgAbn2JA |      5 |
| mlBC3pN9GXlUUfQi1qBBZA | KoIRdcIfh3XWxiCeV1BDmA |      3 |
+------------------------+------------------------+--------+

공통된 모든 행의 데이터 프레임을 구하려고 합니다.user_id인에df1그리고.df2. (즉, a일 경우)user_id둘다에 있습니다df1그리고.df2, 출력 데이터 프레임에 두 행 포함)

저는 이것에 접근할 수 있는 많은 방법들을 생각할 수 있지만, 그들은 모두 저를 투박하다고 생각합니다.예를 들어, 우리는 모든 독특한 점을 찾을 수 있었습니다.user_ids 각각의 데이터 프레임에서, 각각의 집합을 생성하고, 그들의 교집합을 찾고, 결과 집합으로 두 데이터 프레임을 필터링하고, 두 필터링된 데이터 프레임을 연결합니다.

그게 최선의 방법일 수도 있지만, 판다가 영리하다는 걸 알아요.이것을 하는 더 간단한 방법이 있습니까?제가 봐왔습니다.merge제게 필요한 건 그게 아닌 것 같아요

제가 이해하는 바로는 이 질문은 이 게시물에서 더 잘 답변되는 것 같습니다.

하지만 간단히 말해서, 이 방법으로 OP에 대한 답은 다음과 같습니다.

s1 = pd.merge(df1, df2, how='inner', on=['user_id'])

그래서.s1열 5개 포함:user_id그리고 각각의 다른 두 열에서.df1그리고.df2.

제가 당신을 정확하게 이해한다면, 당신은 다음의 조합을 사용할 수 있습니다.Series.isin()그리고.DataFrame.append():

In [80]: df1
Out[80]:
   rating  user_id
0       2  0x21abL
1       1  0x21abL
2       1   0xdafL
3       0  0x21abL
4       4  0x1d14L
5       2  0x21abL
6       1  0x21abL
7       0   0xdafL
8       4  0x1d14L
9       1  0x21abL

In [81]: df2
Out[81]:
   rating      user_id
0       2      0x1d14L
1       1    0xdbdcad7
2       1      0x21abL
3       3      0x21abL
4       3      0x21abL
5       1  0x5734a81e2
6       2      0x1d14L
7       0       0xdafL
8       0      0x1d14L
9       4  0x5734a81e2

In [82]: ind = df2.user_id.isin(df1.user_id) & df1.user_id.isin(df2.user_id)

In [83]: ind
Out[83]:
0     True
1    False
2     True
3     True
4     True
5    False
6     True
7     True
8     True
9    False
Name: user_id, dtype: bool

In [84]: df1[ind].append(df2[ind])
Out[84]:
   rating  user_id
0       2  0x21abL
2       1   0xdafL
3       0  0x21abL
4       4  0x1d14L
6       1  0x21abL
7       0   0xdafL
8       4  0x1d14L
0       2  0x1d14L
2       1  0x21abL
3       3  0x21abL
4       3  0x21abL
6       2  0x1d14L
7       0   0xdafL
8       0  0x1d14L

이것은 본질적으로 당신이 관용어를 사용하여 "clunky"라고 설명한 알고리즘입니다.pandas방법들.중복된 행 인덱스를 확인합니다.또한, 이것은 당신에게 다음과 같은 경우에 기대되는 출력을 주지 못합니다.df1그리고.df2중복되는 행 인덱스가 없습니다. 즉, 다음과 같은 경우

In [93]: df1.index & df2.index
Out[93]: Int64Index([], dtype='int64')

실제로 행 인덱스가 동일하지 않으면 예상 출력을 제공하지 않습니다.

SQL에서 이 문제는 다음과 같은 몇 가지 방법으로 해결할 수 있습니다.

select * from df1 where exists (select * from df2 where df2.user_id = df1.user_id)
union all
select * from df2 where exists (select * from df1 where df1.user_id = df2.user_id)

또는 가입 후 비투표(SQL 서버에서 가능)

select
    df1.user_id,
    c.rating
from df1
    inner join df2 on df2.user_i = df1.user_id
    outer apply (
        select df1.rating union all
        select df2.rating
    ) as c

두 번째 것은 다음과 같은 내용으로 팬더로 작성될 수 있습니다.

>>> df1 = pd.DataFrame({"user_id":[1,2,3], "rating":[10, 15, 20]})
>>> df2 = pd.DataFrame({"user_id":[3,4,5], "rating":[30, 35, 40]})
>>>
>>> df4 = df[['user_id', 'rating_1']].rename(columns={'rating_1':'rating'})
>>> df = pd.merge(df1, df2, on='user_id', suffixes=['_1', '_2'])
>>> df3 = df[['user_id', 'rating_1']].rename(columns={'rating_1':'rating'})
>>> df4 = df[['user_id', 'rating_2']].rename(columns={'rating_2':'rating'})
>>> pd.concat([df3, df4], axis=0)
   user_id  rating
0        3      20
0        3      30

이렇게 하면 됩니다.n데이터 프레임 및k열을 사용하여 열을 만듭니다.pd.Index.intersection:

import pandas as pd
from functools import reduce
from typing import Union

def dataframe_intersection(
    dataframes: list[pd.DataFrame], by: Union[list, str]
) -> list[pd.DataFrame]:
    set_index = [d.set_index(by) for d in dataframes]
    index_intersection = reduce(pd.Index.intersection, [d.index for d in set_index])
    intersected = [df.loc[index_intersection].reset_index() for df in set_index]

    return intersected

df1 = pd.DataFrame({"user_id":[1,2,3], "business_id": ['a', 'b', 'c'], "rating":[10, 15, 20]})
df2 = pd.DataFrame({"user_id":[3,4,5], "business_id": ['c', 'd', 'e'], "rating":[30, 35, 40]})
df3 = pd.DataFrame({"user_id":[3,3,3], "business_id": ['f', 'c', 'f'], "rating":[50, 70, 80]})

df_list = [df1, df2, df3]

이것은.

>>> pd.concat(dataframe_intersection(df_list, by='user_id'))
   user_id business_id  rating
0        3           c      20
0        3           c      30
0        3           f      50
1        3           c      70
2        3           f      80

그리고.

>>> pd.concat(dataframe_intersection(df_list, by=['user_id', 'business_id']))
   user_id business_id  rating
0        3           c      20
0        3           c      30
0        3           c      70

이것은 간단한 해결책입니다.

df1[df1 == df2].dropna

언급URL : https://stackoverflow.com/questions/19618912/finding-common-rows-intersection-in-two-pandas-dataframes