Skip to main content
 首页 » 编程设计

python之使用来自单独表的 ID 对从表中检索行

2025年05月04日16freeliver54

给定两个文件,

  • sentences_detailed.csv 包含 3 列(ID、LANG 和 TEXT)
  • links.csv 包含 2 列(ID1 和 ID2),ID* 链接到sentences_detailed.csv
  • 中的 ID 列

sentences_detailed.csv 示例:

ID LANG TEXT 
123 eng I want you to meet my parents. 
456 eng I'm on your side. 
789 eng I did not want to alarm you.  
567 kor 부모님을 만나길 원해. 
2352 jpn 私はあなたの側にいます。 

links.csv 示例:

ID1 ID2 
123 567 
2352 456 

我如何创建一个新的 DataFrame,以便使用links.csv 中的 ID 对?

所需的输出 DataFrame 应该类似于:

ID1 ID2 LANG1 LANG2 TEXT1 TEXT2 
123 567 eng kor I want you to meet my parents. 부모님을 만나길 원해. 
2352 456 jpn eng 私はあなたの側にいます。I'm on your side. 

我已经试过了:

sent_details_csv = """ID    LANG    TEXT 
123 eng I want you to meet my parents. 
456 eng I'm on your side. 
789 eng I did not want to alarm you.  
567 kor 부모님을 만나길 원해. 
2352    jpn 私はあなたの側にいます。""" 
 
links_csv = """ID1  ID2 
123 567 
2352    456 
""" 
 
from io import StringIO 
 
sent_details = pd.read_csv(StringIO(sent_details_csv), sep='\t') 
links = pd.read_csv(StringIO(links_csv), sep='\t') 
 
for idx, row in links.iterrows(): 
    src_idx, trg_idx = row['ID1'], row['ID2'] 
 
    try: 
        src = sent_details[sent_details['ID'] == src_idx][['TEXT', 'LANG']].iloc[0] 
        trg = sent_details[sent_details['ID'] == trg_idx][['TEXT', 'LANG']].iloc[0] 
    except:  
        continue 
 
    print('\t'.join(map(str, [src_idx, trg_idx, src['LANG'], trg['LANG'], src['TEXT'], trg['TEXT']]))) 

上面的代码适用于小型数据集,但实际 sentences_detailed.csv 有 6,000,000 多行,而 links.csv 有大约 13,000,000 行。

在给定每个 links 行的源和目标 idx 的情况下,尝试过滤掉 sent_details 变得代价高昂。

必须有更好的更“pandas-ic”的方式来做到这一点。


完整数据集在https://www.kaggle.com/alvations/how-to-get-parallel-sentences-from-tatoeba上

Dark、Zero 和 COLDSPEED 的答案很好,但是当 sentences_detailed.csv 和 links.csv 中存在重复项时,它们会抛出一些错误。

请您参考如下方法:

一种快速的方法是分而治之,即

one = df[df['ID'].isin(links['ID1'])].copy() 
two = df[df['ID'].isin(links['ID2'])].copy() 
 
two['NEW_ID'] = two['ID'].map(links.set_index('ID2')['ID1']) 
 
one.merge(two,left_on='ID',right_on='NEW_ID',suffixes=('1', '2')) 
 
     ID1 LANG1                         TEXT1       ID2  LANG2       TEXT2      NEW_ID   
0   123    eng     I want you to meet my parents.  567    kor  부모님을 만나길 원해.     123   
1  2352    jpn             私はあなたの側にいます。    456    eng  I'm on your side.    2352  

由于存在重复 ID,映射不起作用,因此您可以使用双重合并,即

one.merge(two.merge(links,left_on='ID',right_on='ID2'),left_on='ID',right_on='ID1',suffixes=('1', '2'))) 
 
 ID1 LANG1                           TEXT1  ID2 LANG2              TEXT2  \ 
0   123   eng  I want you to meet my parents.  567   kor       부모님을 만나길 원해.    
1  2352   jpn                    私はあなたの側にいます。  456   eng  I'm on your side.    
 
    ID1  ID2   
0   123  567   
1  2352  456   

根据实际数据,您可以简单地交叉合并相同的数据框,因为您具有相同的列名,即

sec = sent_details.merge(links) 
 
sec.merge(sec, left_on=['Sentence id','Translation id'],right_on=['Translation id','Sentence id'], suffixes=(1,2))