如何在连接时合并大型数据框并消除不相关的列?
How to merge large dataframe on join and eliminate non-relevant columns?
给定一个数据框,其中第一列链接到第 3 列和第 5 列,第 2 列链接到第 4 列和第 6 列。这些列是:
- SRC ID:
SRC
列的唯一索引
- TRG ID:
TRG
列的唯一索引
- SRC LANG:
SRC
列的语言
- TRG LANG:
TRG
列的语言
- SRC:
SRC LANG
指定语言的文本
- TRG:
TRG LANG
指定语言的文本
注:SRC
和TRG
互为翻译。
在代码中:
from io import StringIO
import pandas as pd
instr = """SRC ID TRG ID SRC LANG TRG LANG SRC TRG
8366 170897 fra jpn C'est sec comme la poussière. 砂をかむように味気ないね。
8366 243583 fra eng C'est sec comme la poussière. It's dry as dust.
8366 1840509 fra epo C'est sec comme la poussière. Estas seke, kiel polvo.
8366 4401595 fra tur C'est sec comme la poussière. Toz kadar kuru.
1 77 cmn deu 我們試試看! Lass uns etwas versuchen!
1 1276 cmn eng 我們試試看! Let's try something.
1 2481 cmn spa 我們試試看! ¡Intentemos algo!
1 5350 cmn kor 我們試試看! 뭔가 해보자!
1 344899 cmn jpn 我們試試看! やってみましょう。
1 345549 cmn cmn 我們試試看! 试一下吧。
"""
pd.read_csv(StringIO(instr), sep='\t')
[输出]:
SRC ID TRG ID SRC LANG TRG LANG SRC TRG
0 8366 170897 fra jpn C'est sec comme la poussière. 砂をかむように味気ないね。
1 8366 243583 fra eng C'est sec comme la poussière. It's dry as dust.
2 8366 1840509 fra epo C'est sec comme la poussière. Estas seke, kiel polvo.
3 8366 4401595 fra tur C'est sec comme la poussière. Toz kadar kuru.
4 1 77 cmn deu 我們試試看! Lass uns etwas versuchen!
5 1 1276 cmn eng 我們試試看! Let's try something.
6 1 2481 cmn spa 我們試試看! ¡Intentemos algo!
7 1 5350 cmn kor 我們試試看! 뭔가 해보자!
8 1 344899 cmn jpn 我們試試看! やってみましょう。
9 1 345549 cmn cmn 我們試試看! 试一下吧。
鉴于这样的数据框,如果我们想要提取英日翻译,我如何从 TRG 列转向 SRC 列以获得所需的输出?
170897 243583 eng jpn It's dry as dust 砂をかむように味気ないね。
1276 344899 eng jpn Let's try something. やってみましょう。
我试过这个:
jpn = df[df['TRG LANG'] == 'jpn']
eng = df[df['TRG LANG'] == 'eng']
df2 = pd.merge(right=eng, left=jpn, on='SRC ID')[['TRG ID_x', 'TRG ID_y', 'TRG_x', 'TRG_y']].dropna()
但这有点低效,因为我必须遍历整个数据集两次以分别创建 jpn 和 eng。
整个数据集至少有 12,000,000+ 行。
有更好的方法吗?有什么替代方案 dask
、pandas
或其他数据框解决方案?
可以做出的一个很好的假设是 SRC ID
在 运行 数字中并且数据帧顺序按 SRC ID
.
排序
选项 1
将 set_index
与 drop=False
结合使用,以便将 'TRG LANG'
正确保留在数据框中,并能够同时用作使用 loc
和 unstack
进行过滤的方法
trg_langs = ['eng', 'jpn']
trg = ['TRG ID', 'TRG LANG', 'TRG']
df.set_index('TRG LANG', drop=False).loc[trg_langs] \
.set_index('SRC ID', append=True)[trg].unstack(0)
TRG ID TRG LANG TRG
TRG LANG eng jpn eng jpn eng jpn
SRC ID
1 1276 344899 eng jpn Let's try something. やってみましょう。
8366 243583 170897 eng jpn It's dry as dust. 砂をかむように味気ないね。
选项 2
您可以使用 groupby.cumcount
创建唯一索引然后 unstack
d1 = df.loc[
df['TRG LANG'].isin(['eng', 'jpn']),
['SRC ID', 'TRG ID', 'TRG LANG', 'TRG']
].sort_values(['SRC ID', 'TRG LANG'])
d1.set_index(['SRC ID', d1.groupby('SRC ID').cumcount()]).unstack()
TRG ID TRG LANG TRG
0 1 0 1 0 1
SRC ID
1 1276 344899 eng jpn Let's try something. やってみましょう。
8366 243583 170897 eng jpn It's dry as dust. 砂をかむように味気ないね。
给定一个数据框,其中第一列链接到第 3 列和第 5 列,第 2 列链接到第 4 列和第 6 列。这些列是:
- SRC ID:
SRC
列的唯一索引 - TRG ID:
TRG
列的唯一索引 - SRC LANG:
SRC
列的语言 - TRG LANG:
TRG
列的语言 - SRC:
SRC LANG
指定语言的文本
- TRG:
TRG LANG
指定语言的文本
注:SRC
和TRG
互为翻译。
在代码中:
from io import StringIO
import pandas as pd
instr = """SRC ID TRG ID SRC LANG TRG LANG SRC TRG
8366 170897 fra jpn C'est sec comme la poussière. 砂をかむように味気ないね。
8366 243583 fra eng C'est sec comme la poussière. It's dry as dust.
8366 1840509 fra epo C'est sec comme la poussière. Estas seke, kiel polvo.
8366 4401595 fra tur C'est sec comme la poussière. Toz kadar kuru.
1 77 cmn deu 我們試試看! Lass uns etwas versuchen!
1 1276 cmn eng 我們試試看! Let's try something.
1 2481 cmn spa 我們試試看! ¡Intentemos algo!
1 5350 cmn kor 我們試試看! 뭔가 해보자!
1 344899 cmn jpn 我們試試看! やってみましょう。
1 345549 cmn cmn 我們試試看! 试一下吧。
"""
pd.read_csv(StringIO(instr), sep='\t')
[输出]:
SRC ID TRG ID SRC LANG TRG LANG SRC TRG
0 8366 170897 fra jpn C'est sec comme la poussière. 砂をかむように味気ないね。
1 8366 243583 fra eng C'est sec comme la poussière. It's dry as dust.
2 8366 1840509 fra epo C'est sec comme la poussière. Estas seke, kiel polvo.
3 8366 4401595 fra tur C'est sec comme la poussière. Toz kadar kuru.
4 1 77 cmn deu 我們試試看! Lass uns etwas versuchen!
5 1 1276 cmn eng 我們試試看! Let's try something.
6 1 2481 cmn spa 我們試試看! ¡Intentemos algo!
7 1 5350 cmn kor 我們試試看! 뭔가 해보자!
8 1 344899 cmn jpn 我們試試看! やってみましょう。
9 1 345549 cmn cmn 我們試試看! 试一下吧。
鉴于这样的数据框,如果我们想要提取英日翻译,我如何从 TRG 列转向 SRC 列以获得所需的输出?
170897 243583 eng jpn It's dry as dust 砂をかむように味気ないね。
1276 344899 eng jpn Let's try something. やってみましょう。
我试过这个:
jpn = df[df['TRG LANG'] == 'jpn']
eng = df[df['TRG LANG'] == 'eng']
df2 = pd.merge(right=eng, left=jpn, on='SRC ID')[['TRG ID_x', 'TRG ID_y', 'TRG_x', 'TRG_y']].dropna()
但这有点低效,因为我必须遍历整个数据集两次以分别创建 jpn 和 eng。
整个数据集至少有 12,000,000+ 行。
有更好的方法吗?有什么替代方案 dask
、pandas
或其他数据框解决方案?
可以做出的一个很好的假设是 SRC ID
在 运行 数字中并且数据帧顺序按 SRC ID
.
选项 1
将 set_index
与 drop=False
结合使用,以便将 'TRG LANG'
正确保留在数据框中,并能够同时用作使用 loc
和 unstack
进行过滤的方法
trg_langs = ['eng', 'jpn']
trg = ['TRG ID', 'TRG LANG', 'TRG']
df.set_index('TRG LANG', drop=False).loc[trg_langs] \
.set_index('SRC ID', append=True)[trg].unstack(0)
TRG ID TRG LANG TRG
TRG LANG eng jpn eng jpn eng jpn
SRC ID
1 1276 344899 eng jpn Let's try something. やってみましょう。
8366 243583 170897 eng jpn It's dry as dust. 砂をかむように味気ないね。
选项 2
您可以使用 groupby.cumcount
创建唯一索引然后 unstack
d1 = df.loc[
df['TRG LANG'].isin(['eng', 'jpn']),
['SRC ID', 'TRG ID', 'TRG LANG', 'TRG']
].sort_values(['SRC ID', 'TRG LANG'])
d1.set_index(['SRC ID', d1.groupby('SRC ID').cumcount()]).unstack()
TRG ID TRG LANG TRG
0 1 0 1 0 1
SRC ID
1 1276 344899 eng jpn Let's try something. やってみましょう。
8366 243583 170897 eng jpn It's dry as dust. 砂をかむように味気ないね。