从数据帧中提取特定行

2024-09-29 21:53:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧df1,有两列'ids'和'names'-

ids     names
fhj56   abc
ty67s   pqr
yu34o   xyz

我有另一个数据帧df2,它有一些列-

^{pr2}$

我的结果应该告诉我那些来自df2的用户,他们的值至少包含df1中的一个id,并告诉哪些id负责将它们放入结果表中。结果应该是-

   user     values_responsible     names
   1        ['fhj56']              ['abc']
   3        ['fhj56','ty67s']      ['abc','pqr']

用户2不在结果表中,因为它的值在df1中都不存在。在

我试着按如下方式做-

df2.query('values in @df1.ids')

但这似乎不太管用。在


Tags: 数据用户ididsnamesdf1valuesdf2
3条回答

我将重构您的第二个数据帧(本质上,规范化您的数据库)。有点像

user     gid     id                       
1        1       'fhj56'
1        1       'fg7uy8'
2        1       'glao0'
2        1       'rt56yu'
2        1       're23u'
3        1       'fhj56'
3        1       'ty67s'
3        1       'hgjl09'

然后,只需合并id列上的第一个和第二个数据帧。在

^{pr2}$

您可以排除某些id没有匹配名称的任何gid。在

r[~r[gid].isin(  r[r['names'] == None][gid].unique()  )]

其中r[r['names'] == None][gid].unique()查找所有没有名称的gid,然后r[~r[gid].isin( ... )]只获取不在isin的列表参数中的条目。在


如果有更多的id组,第二个表可能看起来像

user     gid     id                       
1        1       'fhj56'
1        1       'fg7uy8'
1        2       '1asdf3'
1        2       '7ada2a'
1        2       'asd341'
2        1       'glao0'
2        1       'rt56yu'
2        1       're23u'
3        1       'fhj56'
3        1       'ty67s'
3        1       'hgjl09'

相当于

user     values                       
1        ['fhj56','fg7uy8']
1        ['1asdf3', '7ada2a', 'asd341']
2        ['glao0','rt56yu','re23u']
3        ['fhj56','ty67s','hgjl09']

您可以遍历这些行,然后使用.loc和{}从{}中查找匹配的行。我把这个经过过滤的数据帧转换成了字典

ids = []
names = []
users = []
for _, row in df2.iterrows():
    result = df1.loc[df1['ids'].isin(row['values'])]
    if not result.empty:
        ids.append(result['ids'].tolist())
        names.append(result['names'].tolist())
        users.append(row['user'])

>>> pd.DataFrame({'user': users, 'values_responsible': ids, 'names': names})[['user', 'values_responsible', 'names']]
   user values_responsible       names
0     1            [fhj56]       [abc]
1     3     [fhj56, ty67s]  [abc, pqr]

或者,对于整洁的数据:

^{pr2}$

试试这个,使用unnest a list cell的思想。在

Temp_unnest = pd.DataFrame([[i, x]
              for i, y in df['values'].apply(list).iteritems()
                  for x in y], columns=list('IV'))

Temp_unnest['user']=Temp_unnest.I.map(df.user)
df1.index=df1.ids
Temp_unnest.assign(names=Temp_unnest.V.map(df1.names)).dropna().groupby('user')['V','names'].agg({(lambda x: list(x))})


Out[942]: 
                   V       names
            <lambda>    <lambda>
user                            
1            [fhj56]       [abc]
3     [fhj56, ty67s]  [abc, pqr]

相关问题 更多 >

    热门问题