python - 如何正确地将熊猫数据框切片分配给另一个数据框中的值
问题描述
虽然我已经解决了这个问题,但我想知道是否有更直接的方法来完成我的任务。
import pandas as pd
df1 = pd.DataFrame({'position': ['20', '8000', '8000'],
'SNP_ID': ['rs01', 'rs02', 'rs03'],
'SNP_ref': ['A', 'C', 'T'],
'SNP_alts': ['G', 'T','A,G,']})
df2 = pd.DataFrame({'position': ['400', '8000', '90000'],
'SNP_ID': ['', '', ''],
'SNP_ref': ['', '', ''],
'SNP_alts': ['', '',''],
'check_ref':['T','T','A'],
'check_alts':['T','G','A'],
'other_data': ['xx','yy','zz']})
c1 = ['SNP_ID','SNP_ref','SNP_alts']
for i in range(len(df2)):
SNVs = df1[df1['position'] == df2['position'].loc[i]]
if not SNVs.empty:
df2.loc[df2.index[i],c1] = SNVs.loc[SNVs['SNP_ref'] == df2['check_ref'].loc[i],c1].iloc[0]
print(df2)
所以基本上基于一些标准(比这里显示的更多),我想将给定行的三列的值(基于一些标准)分配给另一个 df 中的三列。我只能使用 .tolist() 来实现它。
有没有更直接的方法来实现这一点?
*注意:我知道循环遍历 df 中的行并不是一个好习惯,但据我所知,我目前无法提出更好的解决方案,我必须进行更多比较才能确定要复制哪些行。现在我的dfs相当小,所以时间不是一个大问题。
谢谢哈根
*更新:根据答案,我用更真实的数据集再次修改了我的代码,并让它在没有 .tolist() 的情况下工作
import pandas as pd
df1 = pd.DataFrame({'position': ['20', '8000', '8000'],
'SNP_ID': ['rs01', 'rs02', 'rs03'],
'SNP_ref': ['A', 'C', 'T'],
'SNP_alts': ['G', 'T','A,G,']})
df2 = pd.DataFrame({'position': ['400', '8000', '90000'],
'SNP_ID': ['', '', ''],
'SNP_ref': ['', '', ''],
'SNP_alts': ['', '',''],
'check_ref':['T','T','A'],
'check_alts':['T','G','A'],
'other_data': ['xx','yy','zz']})
c1 = ['SNP_ID','SNP_ref','SNP_alts']
for i in range(len(df2)):
SNVs = df1[df1['position'] == df2['position'].loc[i]]
if not SNVs.empty:
df2.loc[df2.index[i],c1] = SNVs.loc[SNVs['SNP_ref'] == df2['check_ref'].loc[i],c1].iloc[0]
print(df2)
*更新 2 附加比较不检查字母('A'、'T'等)是否在 *_alts 中匹配,但 SNP_alts 可以包含多个由冒号分隔的序列(例如 A、T、G、AA、GG)
import pandas as pd
df1 = pd.DataFrame({'position': ['20', '8000', '8000'],
'SNP_ID': ['rs01', 'rs02', 'rs03'],
'SNP_ref': ['A', 'C', 'T'],
'SNP_alts': ['G', 'T','A,G,']})
df2 = pd.DataFrame({'position': ['400', '8000', '90000'],
'SNP_ID': ['', '', ''],
'SNP_ref': ['', '', ''],
'SNP_alts': ['', '',''],
'check_ref':['T','T','A'],
'check_alts':['T','G','A'],
'other_data': ['xx','yy','zz']})
c1 = ['SNP_ID','SNP_ref','SNP_alts']
for i in range(len(df2)):
SNVs = df1[df1['position'] == df2['position'].loc[i]]
if not SNVs.empty:
bm1 = SNVs['SNP_ref'] == df2['check_ref'].loc[i]
bm2 = SNVs['SNP_alts'].apply(lambda x: True if df2['check_alts'].loc[i] in x.split(',') else False)
if len(SNVs.loc[bm1 & bm2,c1])>0:
df2.loc[df2.index[i],c1] = SNVs.loc[bm1 & bm2,c1].iloc[0]
print(df2)
解决方案
与重命名列一起使用DataFrame.update
以进行正确匹配:
c1 = ['SNP_ID','SNP_ref','SNP_alts']
c2 = ['name','ref','alts']
d = dict(zip(c2, c1))
#for align values by column position
df11 = df1.set_index(['position','SNP_ref'])
df22 = df2.set_index(['position','check_ref'])
df22.update(df11.rename(columns=d))
df22 = df22.reset_index().reindex(df2.columns, axis=1)
print (df22)
position SNP_ID SNP_ref SNP_alts check_ref other_data
0 400 T xx
1 8000 rs03 A T yy
2 90000 A zz
推荐阅读
- flutter - 如何在颤动中设置文本可点击获取识别器错误
- python - 我在创建 EC2(Python)时尝试在 S3 存储桶中编写 xlsx 工作簿,但出现错误。我该如何解决这些错误?
- visual-studio - MSBuild 忽略所需的配置
- mysql - 查询以获取两个表中每个 ID 的计数
- python - Python:numpy:检测到解释器更改 - 每个进程只能将这个模块加载到一个解释器中
- sql-server - 如何使用“赋予某些不同行相同的身份”的选项来创建计数器(身份)?
- python - 我的函数中的打印语句出现语法错误。我不知道我做错了什么
- vba - 使用两列创建字典并根据单元格值提取值
- python - 如何自定义 Python 的方法解析顺序(mro)?
- arrays - 如何检查数组是否有超过 2 个重复元素