【问题标题】:Iterate over dataframe within condition append list迭代条件追加列表中的数据帧
【发布时间】:2020-11-05 08:50:21
【问题描述】:

我在 for 循环中将行附加到 pandas DataFrame。我想检查我的 ab 文件中的所有日期变化:

df = pd.DataFrame({'id':[1,1,2,2,3],
                 'DATE_FIRST':['01/04/2020','01/05/2020','01/05/2020',
                         '01/06/2020','03/06/2020'],
                 'DATE_LAST':['05/05/2020','05/05/2020','02/06/2020',
                          '02/06/2020','05/06/2020']})

    id  DATE_FIRST  DATE_LAST
0   1   01/04/2020  05/05/2020
1   1   01/05/2020  05/05/2020
2   2   01/05/2020  02/06/2020
3   2   01/06/2020  02/06/2020
4   3   03/06/2020  05/06/2020

此示例中的偏移是索引 0 处的 ID :1 其 DATE_LAST 大于索引 1 的 DATE_FIRST。另一方面,ID 2 相同,ID 3 是正确的。

df的循环结果应该是这样的:

id  DATE_FIRST  DATE_LAST
1   01/04/2020  05/05/2020
2   01/05/2020  02/06/2020
3   03/06/2020  05/06/2020

列表的结果result

[1,2]

目标是输出列表 result 中任何异常的 id,当然还要纠正差异并返回一个干净的文件 df

异能者

任何人都可以突出显示我缺少什么以使附加语句起作用吗?这是我尝试做的:

def absence (df):
    i = 2
    result=[]
    line=[]
    while i <= len(df):
        for i in df.id :
            if df["DATE_FIRST"].iloc[i-1] <= df["DATE_FIRST"].iloc[i] <= df["DATE_LAST"].iloc[i-1]:
               if df["DATE_LAST"].iloc[i] <= df["DATE_LAST"].iloc[i-1]:
                    result=result.append(int(df.index[i]))
                    df=df.drop(df.index[i])
                    i = i - 1

                elif df["DATE_LAST"].iloc[i] > df["DATE_LAST"].iloc[i-1]:

                     line= (df["DATE_LAST"].iloc[i-1] == df["DATE_LAST"].iloc[i])
                     result=result.append(int(df.index[i]))
                     del(line)
                i = i - 1
            else:
                i = i + 1
        break
    return(result)
    return(df)

【问题讨论】:

  • 嗨,Soufiane,您能否举一个示例数据框说明最终结果应该是什么样的?你能举例说明你认为什么是异常吗?
  • 嗨,现在更清楚了吗?谢谢
  • 我添加了一个你的起始 df 的例子,让它更清楚一点。为什么要从您的 df 中删除第 1 行和第 3 行?这对我来说仍然不清楚。你能解释为什么这些是异常情况以及为什么应该从你的 df 中删除它们吗?
  • 是的,谢谢,避免 DATE_FIRST 和 DATE_LAST 之间没有相同 ID 的间隙。我修改了想要的结果
  • 我的循环中描述了异常情况

标签: python pandas


【解决方案1】:

您的异常对我来说并不完全清楚,但这样的解决方案应该会让您朝着正确的方向前进。
我的猜测是您也想查看每个 ID。

我正在使用 .shift() 查看上一行。

在使用 pandas 时要记住一件事:尽量不要使用 for 循环,它们确实会使事情变慢。

代码的工作示例:

import numpy as np
import pandas as pd

df = pd.DataFrame({
    'id':[1, 1, 2, 2],
    'DATE_FIRST':['01/04/2020','01/05/2020','01/05/2020','01/06/2020'],
    'DATE_LAST':['05/05/2020','05/05/2020','02/06/2020','02/06/2020'],
})

df['DATE_FIRST'] = pd.to_datetime(df['DATE_FIRST'], dayfirst=True)
df['DATE_LAST'] = pd.to_datetime(df['DATE_LAST'], dayfirst=True)

df = df.sort_values(by=['id', 'DATE_FIRST', 'DATE_LAST'])

df['previous_date_first'] = df.groupby('id')['DATE_FIRST'].transform('shift')
df['previous_date_last'] = df.groupby('id')['DATE_LAST'].transform('shift')

rows_to_delete = (
    (df['DATE_FIRST'] > df['previous_date_first']) 
    & (df['DATE_LAST'] <= df['previous_date_last'])
)
    
df[~rows_to_delete]

    id  DATE_FIRST  DATE_LAST
0   1   2020-04-01  2020-05-05
2   2   2020-05-01  2020-06-02

【讨论】:

  • 好吧,您可以将变量 rows_to_delete 更改为您想要的任何条件,也许您必须尝试更改一下
猜你喜欢
  • 2013-02-17
  • 2020-05-09
  • 2020-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-03
  • 2018-11-26
  • 2018-01-16
相关资源
最近更新 更多