Python 从数据帧中提取特定行
我有一个数据帧df1,有两列“id”和“name”-Python 从数据帧中提取特定行,python,pandas,Python,Pandas,我有一个数据帧df1,有两列“id”和“name”- ids names fhj56 abc ty67s pqr yu34o xyz 我有另一个数据帧df2,其中一些列- user values 1 ['fhj56','fg7uy8'] 2 ['glao0','rt56yu','re23u'] 3 ['fhj56','ty67s','hgjl09'] 我的结果应该给我那个些来自
ids names
fhj56 abc
ty67s pqr
yu34o xyz
我有另一个数据帧df2,其中一些列-
user values
1 ['fhj56','fg7uy8']
2 ['glao0','rt56yu','re23u']
3 ['fhj56','ty67s','hgjl09']
我的结果应该给我那个些来自df2的用户,这些用户的值至少包含来自df1的一个ID,并告诉我哪些ID负责将它们放入结果表中。结果应该是这样的-
user values_responsible names
1 ['fhj56'] ['abc']
3 ['fhj56','ty67s'] ['abc','pqr']
用户2不在结果表中,因为它的值在df1中都不存在
我试着做如下的事情-
df2.query('values in @df1.ids')
但这似乎不太管用。我将从本质上重构您的第二个数据帧,规范化您的数据库。差不多
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列上的第一个和第二个数据帧
r = df2.merge(df1, left_on='id', right_on='ids', how='left')
您可以排除某些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']
我将重构您的第二个数据帧,使您的数据库正常化。差不多
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列上的第一个和第二个数据帧
r = df2.merge(df1, left_on='id', right_on='ids', how='left')
您可以排除某些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和isin从df2中查找匹配的行。我将这个过滤后的数据帧转换成了一个字典
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]
或者,对于整洁的数据:
ids = []
names = []
users = []
for _, row in df2.iterrows():
result = df1.loc[df1['ids'].isin(row['values'])]
if not result.empty:
ids.extend(result['ids'].tolist())
names.extend(result['names'].tolist())
users.extend([row['user']] * len(result['ids']))
>>> pd.DataFrame({'user': users, 'values_responsible': ids, 'names': names})[['user', 'values_responsible', 'names']])
user values_responsible names
0 1 fhj56 abc
1 3 fhj56 abc
2 3 ty67s pqr
您可以遍历这些行,然后使用.loc和isin从df2中查找匹配的行。我将这个过滤后的数据帧转换成了一个字典
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]
或者,对于整洁的数据:
ids = []
names = []
users = []
for _, row in df2.iterrows():
result = df1.loc[df1['ids'].isin(row['values'])]
if not result.empty:
ids.extend(result['ids'].tolist())
names.extend(result['names'].tolist())
users.extend([row['user']] * len(result['ids']))
>>> pd.DataFrame({'user': users, 'values_responsible': ids, 'names': names})[['user', 'values_responsible', 'names']])
user values_responsible names
0 1 fhj56 abc
1 3 fhj56 abc
2 3 ty67s pqr
试试这个,使用取消列表单元格的想法
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]
试试这个,使用取消列表单元格的想法
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]
熊猫的逐行操作是解决问题的一种相当肮脏的方式。这是一个很好的解释。在许多情况下,可以通过逐行迭代直观地解决的数据帧问题也可以通过cleaver过滤或应用apply或map函数来解决。是的,逐行不是最有效的,但这是因为数据一开始就不整洁。在熊猫中逐行操作是解决问题的一种相当肮脏的方式。这是一个很好的解释。在许多情况下,可以通过逐行迭代直观地解决的数据帧问题也可以通过cleaver筛选或应用apply或map函数来解决。是的,逐行不是最有效的,但这是因为数据一开始就不整洁。您需要取消列值的设置您需要取消列值的设置