我有一个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
所以基本上跳过具有相同UniqueID
和Status
的条目。如果它是新的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
答案 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]])
选项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'])