2016-10-17 4 views
0

私はcsvを持っています。特定の基準に基づいて更新したいです。例:CSVファイルを連結して2つの列で重複をフィルタリングする

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'])

しかし、それは予想通り、すべての重複を落としました。配列のキーに第二のカラム(unique id)をキープ

cat csv csv1 | awk '{

ラインでシーケンスとitereteラインに

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

サブセット化* *名を追加しないのはなぜ? – Parfait

+0

名前は必ずしも一意ではありません –

+1

問題は再現できません。その除外されたレコードが表示されます。 [docs](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.from_csv.html)からの 'pd.DataFrame.from_csv'の代わりに' pd.read_csv'を使用すると*落胆した*メソッド、あなたは望みの結果を得ますか? – Parfait

答えて

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
​​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

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

説明

印刷、これらのファイルを:をもたらしました値として3番目の列を指定します。配列要素が存在しない場合、または値が第1に等しくない(それは、これは、その行の最初の出現であることを意味する)、確認(それは値が変更されたことを意味する)

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

単に配列値を行を印刷し、設定

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

なら端

}

awkが終了 }'

関連する問題