如何过滤包含一列相似模式但另一列值不同的行

时间:2020-07-14 08:32:16

标签: python pandas

我在熊猫中有这个数据框:

For q = 1 To v
                    
    ExpectedFeesTbl.ListRows.Add (lRow + 1)
    ExpectedFeesTbl.ListRows(lRow).Range.Copy
    ExpectedFeesTbl.ListRows(lRow + 1).Range.PasteSpecial Paste:=xlPasteFormats
    ExpectedFeesTbl.ListRows(lRow + 1).Range.PasteSpecial Paste:=xlPasteFormulas
                        
    Application.CutCopyMode = False
Next q

如您所见,某些值的前9个字符在“绑定”列中相同。我将获得此数据帧的一个子集,对于第10个字符等于“ A”的每个值,我想获得前9个字符相同且第10个字符等于“ T”的值。之后,如果“ A”和“ T”债券的发行日期不同,那么我要过滤这两个债券。

例如第0个索引的bond值与第3个和第4个索引的值具有相同的模式,但第0个和第4个索引的发行日期相同,所以我想过滤第0和第3行。另一方面,第一个指数的债券价值与第五个指数具有相同的模式,但是它们的发行日期相同,所以我不想过滤它们。

毕竟,我想获得以下数据框:

df = pd.DataFrame(
             {"bond": ["XSD070623A17","XSD090222A10","XSD100221A18", "XSD070623T15",
                        "XSD070623T23","XSD090222T32","XSD100221T11"],

             "issue_date":["01.01.2020", "03.05.2020", "05.02.2020", "10.11.2019",
                            "01.01.2020", "03.05.2020", "12.10.2020"]
             }
             )
df


    bond            issue_date
0   XSD070623A17    01.01.2020
1   XSD090222A10    03.05.2020
2   XSD100221A18    05.02.2020
3   XSD070623T15    10.11.2019
4   XSD070623T23    01.01.2020
5   XSD090222T32    03.05.2020
6   XSD100221T11    12.10.2020

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

嗨,我之前曾尝试过同样的问题。我们可以在df['bond'].str.contains()和此处使用正则表达式,因为您只希望包含XSD070623XSD100221的行,并且还希望删除具有相同issue-date值的行。 这是我所做的:

#your df:
>>> df
           bond  issue_date
0  XSD070623A17  01.01.2020
1  XSD090222A10  03.05.2020
2  XSD100221A18  05.02.2020
3  XSD070623T15  10.11.2019
4  XSD070623T23  01.01.2020
5  XSD090222T32  03.05.2020
6  XSD100221T11  12.10.2020

现在应用正则表达式来满足您对bond列的第一个条件,并删除issue-date列的重复项并考虑第一个,我做了:

>>> df[df['bond'].str.contains('XSD070623|XSD100221')].drop_duplicates(subset='issue_date', keep="first")
           bond  issue_date
0  XSD070623A17  01.01.2020
2  XSD100221A18  05.02.2020
3  XSD070623T15  10.11.2019
6  XSD100221T11  12.10.2020

'XSD070623|XSD100221'之上将被视为正则表达式,我们将在issue-date列中删除重复项,并保留第一个(对于我们而言)。

答案 1 :(得分:1)

这是不需要任何硬编码的答案。

第一步:按应该相等的前9个字符以及issue_date分组。实际上,您不需要考虑A或T是第十个字符的情况。

已做出以下假设:

  • 索引没关系
  • 当键的前9个字符相同时:仅保留第一个出现的
df_grouped = (df.groupby([df.bond.str[:9], df.issue_date])
                .agg({'bond': ['first', 'nunique']}))

                                  bond
                     first        nunique
bond      issue_date  
XSD070623 01.01.2020 XSD070623A17 2
XSD070623 10.11.2019 XSD070623T15 1
XSD090222 03.05.2020 XSD090222A10 2
XSD100221 05.02.2020 XSD100221A18 1
XSD100221 12.10.2020 XSD100221T11 1

第二步:堆叠分组的数据帧

df_grouped = df_grouped.unstack()

第三步:筛选出只有一个发行日期的行,以共享前9个字符的债券。然后,堆叠结果,并重置索引

df_grouped[df_grouped['nunique'].count(axis=1) > 1].stack().reset_index()

  bond      issue_date first        nunique
0 XSD070623 01.01.2020 XSD070623A17 2.0
1 XSD070623 10.11.2019 XSD070623T15 1.0
2 XSD100221 05.02.2020 XSD100221A18 1.0
3 XSD100221 12.10.2020 XSD100221T11 1.0

最后一步:保留有用的列

df_grouped[['first', 'issue_date']].rename(columns={'first': 'bond'})
  first issue_date
0 XSD070623A17 01.01.2020
1 XSD070623T15 10.11.2019
2 XSD100221A18 05.02.2020
3 XSD100221T11 12.10.2020

请在更大的数据集上尝试一下,让我知道是否需要任何改进:)