【问题标题】:How to create new dataframe with only rows that have been changed in the another dataframe?如何创建仅包含另一个数据框中已更改的行的新数据框?
【发布时间】:2021-01-14 07:28:09
【问题描述】:

我想创建一个仅包含已更改行的新 csv 文件。

条件是:

import pandas as pd
df = pd.read_csv("sample.csv", delimiter='')

df['Part Number'] = df['Part Number'].astype(str).str.replace('+','-PLUS')
df['Part Number'] = df['Part Number'].astype(str).str.replace('/','-SLASH-')
df['Part Number'] = df['Part Number'].astype(str).str.replace('\\','-SLASH-')
df['Part Number'] = df['Part Number'].astype(str).str.replace(' ','-')
df['Part Number'] = df['Part Number'].astype(str).str.replace('_','-')
df['Part Number'] = df['Part Number'].astype(str).str.replace('.','-')
df['Part Number'] = df['Part Number'].astype(str).str.replace('"','')
df['Part Number'] = df['Part Number'].astype(str).str.replace('(','')
df['Part Number'] = df['Part Number'].astype(str).str.replace(')','')
df['Part Number'] = df['Part Number'].astype(str).str.replace('%','-')
# It can be more these are examples.

现在我想创建新的数据框: 这应该只列出零件号已被替换的行。

【问题讨论】:

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


【解决方案1】:

尝试存储原始值并稍后进行比较:

original = df['Part Number'].copy()

#...Changes happen here...

new_df = df[df['Part Number'] != original].join(original, rsuffix = " Changed")

【讨论】:

    【解决方案2】:

    这对我有用,来自 Pablo C:

    import pandas as pd
    df = pd.read_csv('sample.csv')
    original = df['Part Number'].copy()
    
    final_df = df.reindex(['ID','Part Number','Changed Part Number'],axis=1)
    df['Part Number']= df['Part Number'].astype(str).str.replace('=', 'Equals')
    final_df['Changed Part Number'] = final_df['Changed Part Number'].fillna(df['Part Number'])
    
    new_df = final_df[df['Part Number'] != original].copy()
    new_df
    

    【讨论】:

      【解决方案3】:

      由于上面的两个答案很好地解决了这个问题,出于好奇,我对数据进行了一个小模拟,并比较了两种方法的运行时间。我把它贴在这里,以防它对其他人有用。

      形状为(400000, 2)的数据框的执行时间:

      • 17.8s执行,完成时间 2021-01-14 09:24:38
      • 执行于 17.5s,完成时间 09:24:56 2021-01-14

      所以基本上,执行时间是可比的。

      感谢 Pablo C 和 Jezrael 的分享。氪

      Method proposed by Pablo C

      import pandas as pd
      
      df = pd.DataFrame({'Part Number': ['aa', 'bb'], 'other':[1, 2]})
      # print(df)
      df = pd.concat([df] * 200000, ignore_index=True)
      
      original = df['Part Number'].copy()
      
      #...Changes happen here...
      df['Part Number'] = df['Part Number'].apply(lambda x: "ab" if "aa" in x else x)
      
      
      #print('after change', df)
      new_df = df[df['Part Number'] != original].copy()
      print( new_df.head(3))
      
        Part Number  other
      0          ab      1
      2          ab      1
      4          ab      1
      

      Method proposed by Jezrael

      df = pd.DataFrame({'Part Number': ['aa', 'bb'], 'other':[1, 2]})
      df = pd.concat([df] * 200000, ignore_index=True)
      # print(df)
      orig = df['Part Number'].astype(str)
      
      #...Changes happen here...
      df['Part Number'] = df['Part Number'].apply(lambda x: "ab" if "aa" in x else x)
      
      df1 = df[orig.str.contains('|'.join(d1.keys()))]
      print(df1.head(3))
      
        Part Number  other
      0          ab      1
      2          ab      1
      4          ab      1
      

      【讨论】:

        【解决方案4】:

        首先,您可以通过创建字典来简化替换,在字典理解中转义正则表达式并传递给Series.replace

        df = pd.DataFrame({'Part Number':['8/()2-2','3+/5==3-\\5[]',
                                        '3-]%[ [";','5']})
                
        import re    
        
        d = {'+':'-PLUS',
             '/':'-SLASH-',
             '\\':'-SLASH-',
             ' ':'-',
             '_':'-',
             '.':'-',
            '"':'',
            '(':'',
            ')':'',
            '%':'-'
        }
           
        d1 = {rf"{re.escape(k)}":v for k, v in d.items()}
        
        orig = df['Part Number'].astype(str)
        df['Part Number'] = orig.replace(d1, regex=True)
        print (df)
                            Part Number
        0                   8-SLASH-2-2
        1  3-PLUS-SLASH-5==3--SLASH-5[]
        2                      3-]-[-[;
        3                             5
        

        然后对于过滤器将boolean indexing 中的行替换为Series.ne

        df1 = df.assign(Original = orig)[df['Part Number'].ne(orig)]
        print (df1)
                            Part Number      Original
        0                   8-SLASH-2-2       8/()2-2
        1  3-PLUS-SLASH-5==3--SLASH-5[]  3+/5==3-\5[]
        2                      3-]-[-[;     3-]%[ [";
        

        【讨论】:

          猜你喜欢
          • 2022-06-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-02-02
          • 1970-01-01
          相关资源
          最近更新 更多