Python pandas:合并列值if not None (join string),然后只保留第一行
Python pandas: merge column values if not None (join string), and then only keep first row
这里是有代表性的数据
asker1 = ['Peter', 'Markus', 'Rebecca', None, None, None, None, 'Sofie', 'Jesus', None]
que_text = ['QQQ', 'RRR', 'GGG', 'GGG', None, None, None, None, 'WWW', 'AAA']
date = ['14.10.2001', '12. October 1999', '14.10.2004', '14.10.2002', '14.10.2002', '14.10.2002', '14.10.2002', '14.10.2010', '14.10.2000', '14.10.2000']
identifier = ['Drs_2_00028_1', 'Drs_2_00029_1', 'Drs_2_00030_1_KlAnfr_000.tif', 'Drs_2_00030_1_KlAnfr_001.tif', 'Drs_2_00030_1_KlAnfr_002.tif', 'Drs_2_00030_1_KlAnfr_003.tif', 'Drs_2_00030_1_KlAnfr_004.tif', 'Drs_2_00052_1', 'Drs_2_00054_1_KlAnfr_000.tif', 'Drs_2_00054_1_KlAnfr_001.tif']
df2 = pd.DataFrame(
list(zip(asker1, que_text, date, identifier)),
columns =['asker1', 'que_text', 'date', 'identifier']
)
我正在从文件夹中的单个文件图片中提取文本信息。其中一些图片是连接的,这意味着它们代表后续页面(000
=第一页;001
=第二页)但并非所有图片都连接到另一个文件。
我在我的 pandas df2
.
中读取了我想要的每个文件的信息作为一行
我的目标是每秒合并(001
)/第三(002
)/第四(003
)/.. . que_text
值到其第一页(000
)行('que_text'),只要该值不是 None
。如果行(文件)连接到另一行(文件),'identifier'
列包含以下字符序列:_KlAnfr_\d{3}.tif
为什么只合并 que_text
值?由于我从正则表达式创建数据框,匹配原始字符串开头和结尾的某些单词,它们无法匹配每个 second/third/forth/... 页面,因为缺少正则表达式将捕获的唯一起始词(因为到目前为止我已经分别处理了每个文件。
例如第 9 行和第 10 行(均由标识符 col 连接):我想要一个字符串 'WWW AAA'
(merged 'que_text[8]=WWW' and que_text[9]=AAA
),以便尝试使用正则表达式进行匹配(再次) 随后
合并各自的 que_text
值后,除了第一行之外的所有行都应该被删除,即只有编号为 000
的行应该被保留。
示例的预期结果是:
asker1 que_text date identifier
0 Peter QQQ 14.10.2001 Drs_2_00028_1
1 Markus RRR 12. October 1999 Drs_2_00029_1
2 Rebecca GGG GGG 14.10.2004 Drs_2_00030_1_KlAnfr_000.tif
3 Sofie None 14.10.2010 Drs_2_00052_1
4 Jesus WWW AAA 14.10.2000 Drs_2_00054_1_KlAnfr_000.tif
这个
def merge_qts(sdf):
sdf.que_text = " ".join(
str(qt) for _, qt in sorted(zip(sdf.No, sdf.que_text))
if qt is not None
)
return sdf
mask = df2.identifier.str.contains(r"_KlAnfr_\d{3}\.tif$")
df3 = df2.loc[mask, ["que_text", "identifier"]]
pattern = r"^(.*?_KlAnfr)_(\d{3}).tif$"
df3[["ID", "No"]] = df2.identifier.str.extract(pattern)
df2.loc[mask, "que_text"] = df3.groupby("ID").apply(merge_qts).que_text
df2 = df2[~df2.identifier.str.contains(r"_KlAnfr_\d{2}[1-9]\.tif$")].reset_index(drop=True)
结果
asker1 que_text date identifier
0 Peter QQQ 14.10.2001 Drs_2_00028_1
1 Markus RRR 12. October 1999 Drs_2_00029_1
2 Rebecca GGG GGG 14.10.2004 Drs_2_00030_1_KlAnfr_000.tif
3 Sofie None 14.10.2010 Drs_2_00052_1
4 Jesus WWW AAA 14.10.2000 Drs_2_00054_1_KlAnfr_000.tif
一些解释:
- 第一步是构建
mask
并将需要处理的数据提取到 df3
中。
- 然后通过从列
identifier
中提取标识分组 (-> ID
) 和数字 (-> [=18) 的第一部分,将 2 列添加到 df3
=]).
- 之后
groupby
ID
列,合并 que_text
条目,并将 df2
中的原始 que_text
列替换为合并后的 que_text
列。
- 最后删除所有
identifier
列的值与模式匹配但数字部分不是 '000'
. 的行
替代方法:
def merge_qts(sdf):
if sdf.shape[0] > 1:
sdf.que_text.iat[0] = " ".join(
qt for _, qt in sorted(zip(sdf.No, sdf.que_text))
if qt is not None
)
return sdf.iloc[0, :]
pattern = r"^(.*?_KlAnfr)_(\d{3}).tif$"
df2[["ID", "No"]] = df2.identifier.str.extract(pattern)
df2.ID[df2.ID.isna()] = range(df2.ID.isna().sum())
df2 = (
df2.groupby("ID", as_index=False, sort=False)
.apply(merge_qts)
.drop(columns=["ID", "No"])
)
这里是有代表性的数据
asker1 = ['Peter', 'Markus', 'Rebecca', None, None, None, None, 'Sofie', 'Jesus', None]
que_text = ['QQQ', 'RRR', 'GGG', 'GGG', None, None, None, None, 'WWW', 'AAA']
date = ['14.10.2001', '12. October 1999', '14.10.2004', '14.10.2002', '14.10.2002', '14.10.2002', '14.10.2002', '14.10.2010', '14.10.2000', '14.10.2000']
identifier = ['Drs_2_00028_1', 'Drs_2_00029_1', 'Drs_2_00030_1_KlAnfr_000.tif', 'Drs_2_00030_1_KlAnfr_001.tif', 'Drs_2_00030_1_KlAnfr_002.tif', 'Drs_2_00030_1_KlAnfr_003.tif', 'Drs_2_00030_1_KlAnfr_004.tif', 'Drs_2_00052_1', 'Drs_2_00054_1_KlAnfr_000.tif', 'Drs_2_00054_1_KlAnfr_001.tif']
df2 = pd.DataFrame(
list(zip(asker1, que_text, date, identifier)),
columns =['asker1', 'que_text', 'date', 'identifier']
)
我正在从文件夹中的单个文件图片中提取文本信息。其中一些图片是连接的,这意味着它们代表后续页面(000
=第一页;001
=第二页)但并非所有图片都连接到另一个文件。
我在我的 pandas df2
.
我的目标是每秒合并(001
)/第三(002
)/第四(003
)/.. . que_text
值到其第一页(000
)行('que_text'),只要该值不是 None
。如果行(文件)连接到另一行(文件),'identifier'
列包含以下字符序列:_KlAnfr_\d{3}.tif
为什么只合并 que_text
值?由于我从正则表达式创建数据框,匹配原始字符串开头和结尾的某些单词,它们无法匹配每个 second/third/forth/... 页面,因为缺少正则表达式将捕获的唯一起始词(因为到目前为止我已经分别处理了每个文件。
例如第 9 行和第 10 行(均由标识符 col 连接):我想要一个字符串 'WWW AAA'
(merged 'que_text[8]=WWW' and que_text[9]=AAA
),以便尝试使用正则表达式进行匹配(再次) 随后
合并各自的 que_text
值后,除了第一行之外的所有行都应该被删除,即只有编号为 000
的行应该被保留。
示例的预期结果是:
asker1 que_text date identifier
0 Peter QQQ 14.10.2001 Drs_2_00028_1
1 Markus RRR 12. October 1999 Drs_2_00029_1
2 Rebecca GGG GGG 14.10.2004 Drs_2_00030_1_KlAnfr_000.tif
3 Sofie None 14.10.2010 Drs_2_00052_1
4 Jesus WWW AAA 14.10.2000 Drs_2_00054_1_KlAnfr_000.tif
这个
def merge_qts(sdf):
sdf.que_text = " ".join(
str(qt) for _, qt in sorted(zip(sdf.No, sdf.que_text))
if qt is not None
)
return sdf
mask = df2.identifier.str.contains(r"_KlAnfr_\d{3}\.tif$")
df3 = df2.loc[mask, ["que_text", "identifier"]]
pattern = r"^(.*?_KlAnfr)_(\d{3}).tif$"
df3[["ID", "No"]] = df2.identifier.str.extract(pattern)
df2.loc[mask, "que_text"] = df3.groupby("ID").apply(merge_qts).que_text
df2 = df2[~df2.identifier.str.contains(r"_KlAnfr_\d{2}[1-9]\.tif$")].reset_index(drop=True)
结果
asker1 que_text date identifier
0 Peter QQQ 14.10.2001 Drs_2_00028_1
1 Markus RRR 12. October 1999 Drs_2_00029_1
2 Rebecca GGG GGG 14.10.2004 Drs_2_00030_1_KlAnfr_000.tif
3 Sofie None 14.10.2010 Drs_2_00052_1
4 Jesus WWW AAA 14.10.2000 Drs_2_00054_1_KlAnfr_000.tif
一些解释:
- 第一步是构建
mask
并将需要处理的数据提取到df3
中。 - 然后通过从列
identifier
中提取标识分组 (->ID
) 和数字 (-> [=18) 的第一部分,将 2 列添加到df3
=]). - 之后
groupby
ID
列,合并que_text
条目,并将df2
中的原始que_text
列替换为合并后的que_text
列。 - 最后删除所有
identifier
列的值与模式匹配但数字部分不是'000'
. 的行
替代方法:
def merge_qts(sdf):
if sdf.shape[0] > 1:
sdf.que_text.iat[0] = " ".join(
qt for _, qt in sorted(zip(sdf.No, sdf.que_text))
if qt is not None
)
return sdf.iloc[0, :]
pattern = r"^(.*?_KlAnfr)_(\d{3}).tif$"
df2[["ID", "No"]] = df2.identifier.str.extract(pattern)
df2.ID[df2.ID.isna()] = range(df2.ID.isna().sum())
df2 = (
df2.groupby("ID", as_index=False, sort=False)
.apply(merge_qts)
.drop(columns=["ID", "No"])
)