【问题标题】:How to remove all elements matching a specific criteria from a list of lists?如何从列表列表中删除与特定条件匹配的所有元素?
【发布时间】:2019-01-01 09:07:15
【问题描述】:

我正在尝试解析包含在 pandas Dataframe 列中的字符串列表并提取一些出生日期(dd.dd.dddd 或 dd/dd/dddd 格式)。我的目标是将它存储在一个名为 date 的新列表中,并保持与我之前的数据框中相同的索引。这是我的第一个示例代码:

date=[]
for i in range(df['Text']):
    a=re.findall(r'[\d]{1,2}[/\.][\d]{1,2}[/\.][\d]{4}', df['Text'][i])
    date.append(a)

但是,如果我只编写这段代码(它解析好的值但没有足够的限制),我会获得出生日期,但也会获得其他一些不太相关的日期:

[[], [], [], [], [], [], [], ['17/02/1997'], ['26.07.1990', '17.03.2014', 
'01.11.2017', '01.07.2013', '06.09.2013', '01.10.2011', '01.06.2013', 
'25.09.2013', '15.03.2014', '15.09.2011', '15.08.2014', '11.09.2009', 
'02.07.2011', '15.09.2008', '30.07.2009', '15.09.2007', '30.07.2008'], [], 
[], [], []]

因此,我知道 2003 年之后的每个日期都不是出生日期。 所以我想要一个只会返回的脚本:

[[], [], [], [], [], [], [], ['17/02/1997'], ['26.07.1990'], [], 
[], [], []]

然后我编写了这个脚本,但似乎我的循环缺少一些日期来检查它是否符合标准(查看打印以检查循环关注的那个):

date=[]
for i in range(df['Text']):
    a=re.findall(r'[\d]{1,2}[/\.][\d]{1,2}[/\.][\d]{4}', df['Text'][i])
    for k in a:
        print(k +"prems")
        if k[-4:].isdigit()==True and int(k[-4:])>2003:
            print(k)
            a.remove(k)
    date.append(a)


[Out]:
17/02/1997prems
26.07.1990prems
17.03.2014prems
17.03.2014
01.07.2013prems
01.07.2013
01.10.2011prems
01.10.2011
25.09.2013prems
25.09.2013
15.09.2011prems
15.09.2011
11.09.2009prems
11.09.2009
15.09.2008prems
15.09.2008
15.09.2007prems
15.09.2007
[[], [], [], [], [], [], [], ['17/02/1997'], ['26.07.1990', '01.11.2017', 
'06.09.2013', '01.06.2013', '15.03.2014', '15.08.2014', '02.07.2011', 
'30.07.2009', '30.07.2008'], [], [], [], []]

考虑到他们回答了循环的标准,有谁明白为什么没有根据这个标准从列表中删除 2003 年之后的某些日期?

如果在正则表达式中有更简单的方法(我是该领域的初学者),那可能也是最好的。


编辑 感谢@Sunitha cmets,我得到了我想要的输出:

date=[]
for i in range(df['Text']):
    a=re.findall(r'[\d]{1,2}[/\.][\d]{1,2}[/\.][\d]{4}', df['Text'][i])
    date.append(a)

#Capture the non birthdate
not_date=[]
for i in range(df['Text']):
    a=re.findall(r'[\d]{1,2}[/\.][\d]{1,2}[/\.][\d]{4}', df['Text'][i])
    for k in a:
        print(k +"prems")
        if k[-4:].isdigit()==True and int(k[-4:])>2003:
            print(k)
            not_date.append(k)

#Remove the non birthdate from the list of list
for k in not_date:
    print(k)
    for i in range(len(date)):
        if k in date[i]:
            date[i].remove(k)
print(date)

非常感谢!

【问题讨论】:

  • 在迭代该列表时从列表中删除元素总是会给我带来问题。您是否考虑过从旧列表构建新列表?
  • 您的意思是创建 len(date) 个列表,其中包含 date 值,然后将条件应用于所有这些新列表?
  • 如果您提供输入列表的样本和相应的所需输出列表,这将使事情变得更加清晰。
  • 我创建了一个新的简单列表,其中包含从第一个代码中获得的所有日期值,但结果相同,标准似乎在 2 个日期中的 1 个日期中被检查...

标签: python regex python-3.x pandas dataframe


【解决方案1】:

正如 Ben Jones 在 cmets Removing elements from a list while iterating over that list always causes problems 中指出的那样。因此,不要从列表a 中删除元素,而是将结果直接附加到列表date

date=[]
for i in range(df['Text']):
    a=re.findall(r'[\d]{1,2}[/\.][\d]{1,2}[/\.][\d]{4}', df['Text'][i])
    for k in a:
        print(k +"prems")
        if k[-4:].isdigit()==True and int(k[-4:])>2003:
            print(k)
            date.append(k)

【讨论】:

  • 谢谢:)。它允许将所有不是生日的日期捕获到一个列表中。但是,这不是我想要的输出,我仍然需要从更复杂的列表中删除所有这些值
  • 即使你的回答是足够的,老实说,这是一个更合适的方法;您始终可以创建一个单独的要删除的对象列表,然后在确定所有需要删除的对象后将其删除。
猜你喜欢
  • 2016-08-16
  • 2016-12-31
  • 1970-01-01
  • 2022-11-14
  • 2015-03-26
  • 1970-01-01
  • 2017-12-15
  • 2020-07-23
  • 1970-01-01
相关资源
最近更新 更多