包含CSV文件,但按2列过滤重复项

2024-05-14 15:44:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个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转换为数据帧并使用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

Tags: csvnameapplestatusfulldropduplicatespear
2条回答

设置

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

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结束 }'

相关问题 更多 >

    热门问题