查询CSV文件,但按2列过滤重复项

时间:2016-10-17 20:03:23

标签: python csv pandas dataframe

我有一个csv我想根据某些标准更新。示例:

csv: 
Name     UniqueID    Status
Apple    1121        Full
Orange   1122        Eaten
Apple    1123        Rotten

新值(也在csv中):

csv1:
Apple    1121        Eaten
orange   1122        Eaten
Pear     1233        Wiggly 

更新后的csv如下所示:

Name     UniqueID    Status
Apple    1121        Full
Orange   1122        Eaten
Apple    1123        Rotten
Pear     1233        Wiggly
Apple    1121        Eaten

所以基本上跳过具有相同UniqueIDStatus的条目。如果它是新的UniqueID或现有的UniqueID以及不同的Status,我希望将其作为单独的行包含在内。因此,从上面的示例orange 1122 Eaten中排除了。

我尝试将csv转换为DataFrame并使用drop_duplicates

data = pd.concat([pd.DataFrame.from_csv(csv, csv1)].drop_duplicates(subset=['Status', 'UniqueID'])

但它可以预见地丢掉了所有重复的内容。结果导致:

    Name     UniqueID    Status
    Apple    1121        Full
    Orange   1122        Eaten
    Apple    1123        Rotten
    Pear     1233        Wiggly
   # Apple    1121        Eaten  <-- this result was excluded

2 个答案:

答案 0 :(得分:0)

cat csv csv1 | awk '{if (!status[$2] || status[$2]!=$3) {print $0; status[$2]=$3} }'

<强>解释

按顺序打印这些文件并逐行迭代

cat csv csv1 | awk '{

将第二列(unique id)保留在数组键中,将第三列保留为值。然后检查,如果数组元素不存在(这意味着这是该行的第一次出现)或者值不等于第三个(这意味着值已经改变)

if (!status[$2] || status[$2]!=$3) {

然后只需打印行并设置数组值

print $0; status[$2]=$3

如果结束

}

awk结束 }'

答案 1 :(得分:0)

设置

import pandas as pd
from StringIO import StringIO

csv = """Name     UniqueID    Status
Apple    1121        Full
Orange   1122        Eaten
Apple    1123        Rotten"""

csv1 = """Name     UniqueID    Status
Apple    1121        Eaten
Orange   1122        Eaten
Pear     1233        Wiggly """

选项1
set_index + combine_first + reduce

def fruit_status1(f):
    return pd.read_csv(StringIO(f), delim_whitespace=True,
                       index_col=['UniqueID', 'Status'])

def update1(d1, d2):
    return d2.combine_first(d1)

reduce(update1, [fruit_status1(f) for f in [csv, csv1]])

enter image description here

选项2
pd.concat + drop_duplicates

def fruit_status2(f):
    return pd.read_csv(StringIO(f), delim_whitespace=True)

pd.concat([fruit_status2(f) for f in [csv, csv1]]) \
    .drop_duplicates(subset=['UniqueID', 'Status'])

enter image description here