首页 > 解决方案 > Pandas 修复数据框

问题描述

我有一个input_df ,里面装满了 +20k 的案例,经过测试并转换为output_df

input_df中的一些案例失败了,然后我们在 output_df 上得到一个 FAIL 输出。如果是这种情况,我们需要修复 input_df(旧)并重新生成一个新的 input_df(新)。所以我们寻求的最终结果是input_df(new) 我们修复它的方法是简单地更改 input_date 中失败案例的日期。我们知道因为 output_df 在 output_result 列中有 FAIL 或 SUCCESS 而失败的案例。

#sample 下面的示例 - 实际的 df 超过 20k 行,即:

输出_df

case_id        output_date        carBrand     ouput_result
1                 01/20/21             001          FAIL
2                 02/21/21             002          SUCCESS  
3                 02/08/20             003          FAIL 
4                 01/07/20             001          FAIL
5                 09/05/20             002          SUCCESS

input_df(旧)

case_id    input_date         carBrand 
    1          01/20/21             001  
    2          02/21/21             002 
    3          02/08/20             003
    4          01/07/20             001
    5          09/05/20             002

修复后的新预期结果(更改日期)=>

input_df(新)

case_id   input_date              carBrand 
    **1          01/13/21             001**  
    2          02/21/21             002 
    **3          02/22/20             003**
    **4          01/28/20             001**
    5          09/05/20             002

input_df 和 output_df 具有匹配的 case_id 列。我们需要做到以下几点

  1. 从 output_df 中获取 FAIL 状态的行case_id

  2. 使用case_id将这些行与 input_df 中的行匹配 例如上面我们看到 case_id 1,3,4 失败了。因此,我们转到 input_df 并查找第 1、3、5 行。=> 失败是因为日期错误;因此我们需要在旧日期的 +- 7 天内选择一个新日期。因此,如果原始 input_df 上的旧日期是 01/20/2020,我们选择的新测试日期可以是 01/27/2020 或 +- 7 天的另一个倍数。即:14,21,28,35..

  3. 现在,我们需要做一个 groupBy(input_carID) 即: inputID 是一组案例。我们这样做是因为我们需要通过不在 groupLevel 引入重复值来修复这些情况。将此视为一组梅赛德斯,或一组福特,迈凯轮等......因此,当我们为 FAIL 案例选择新日期时,我们需要检查某个组中我们选择的日期尚未出现的所有案例之前选择的。=> 所以我们为每个汽车品牌 groupBy() 制作了一组,然后我们修复了每个组中失败的案例。

当我们处理完每个组中的所有 FAIL 案例后,我们现在有了一个新的 input_df(新)。

修复是关于更改 input_df (旧)中的日期,因此获得一个新的 input_df (新)这是我到目前为止所没有的。我没有得到 input_df 的唯一值,并且 input_df 由于某些原因被打印了 3 次。

    import pandas as pd
    import numpy as np
    import datetime
    
    output_df = pd.DataFrame(
    {
    "case_id": [1, 2, 3, 4, 5],
    "output_date": ["2021-01-20", "2021-02-21", "2020-02-08", "2020-01-07", "2020-09-05"],
    "output_carId": ["001", "001", "003", "001", "002"],
    "output_result": ["FAIL", "SUCCESS", "FAIL", "FAIL", "SUCCESS"],
    },
    columns=["case_id", "output_date", "output_carId", "output_result"],
    )
    input_df = pd.DataFrame(
    {
    "case_id": [1, 2, 3, 4, 5],
    "input_date": ["2021-01-20", "2021-02-21", "2020-02-08", "2020-01-07", "2020-09-05"],
    "input_carId": ["001", "001", "003", "001", "002"],
    },
    columns=["case_id", "input_date", "input_carId"],
    )
    
 
    
    def func(x, old_input):
    # print(old_input)
    mask = x['output_result'] == 'FAIL'
    count = mask.sum()
    indexes = x.loc[mask]
    # print(indexes.index)
    arr = np.arange(1, count + 1) * 7
    np.random.shuffle(arr)
    td = pd.to_timedelta(arr, unit='d')
    old_input.loc[indexes.index, 'input_date'] = pd.to_datetime(old_input.loc[indexes.index, 'input_date']) + td
    old_input.loc[indexes.index, 'input_date'] = pd.to_datetime(old_input.loc[indexes.index, 'input_date']).dt.date
    return old_input
    
    
    **new_input** = output_df.groupby('output_carId').apply(lambda x: func(x, input_df))
    print(new_input)

 

标签: pythonpandasdataframe

解决方案


您在 groupby 的每次迭代期间返回一个完整的数据帧。你能用这个吗?独立运行函数中的内容,而不是执行 groupby。

output_df = pd.DataFrame(
    {
    "case_id": [1, 2, 3, 4, 5],
    "output_date": ["2021-01-20", "2021-02-21", "2020-02-08", "2020-01-07", "2020-09-05"],
    "output_carId": ["001", "001", "003", "001", "002"],
    "output_result": ["FAIL", "SUCCESS", "FAIL", "FAIL", "SUCCESS"],
    },
    columns=["case_id", "output_date", "output_carId", "output_result"],
    )

input_df = pd.DataFrame(
    {
    "case_id": [1, 2, 3, 4, 5],
    "input_date": ["2021-01-20", "2021-02-21", "2020-02-08", "2020-01-07", "2020-09-05"],
    "input_carId": ["001", "001", "003", "001", "002"],
    },
    columns=["case_id", "input_date", "input_carId"],
    )

mask = output_df['output_result'] == 'FAIL'
count = mask.sum()
indexes = output_df.loc[mask]
# print(indexes.index)
arr = np.arange(1, count + 1) * 7
np.random.shuffle(arr)
td = pd.to_timedelta(arr, unit='d')
old_input = input_df
old_input.loc[indexes.index, 'input_date'] = pd.to_datetime(old_input.loc[indexes.index, 'input_date']) + td
old_input.loc[indexes.index, 'input_date'] = pd.to_datetime(old_input.loc[indexes.index, 'input_date']).dt.date
old_input

这是新的“old_ouput”​​(不确定我是否理解您的命名法......)。请原谅来自 jupyter notebook 的格式

case_id input_date  input_carId
0   1   2021-02-03  001
1   2   2021-02-21  001
2   3   2020-02-29  003
3   4   2020-01-14  001
4   5   2020-09-05  002

推荐阅读