2017-12-20 11 views
1

クロスリファレンスを含むCSVファイルがあります。つまり、行にラベルが付けられ、列にラベルが付けられ、セルには両方が適用される「X」が含まれます(色と味私たちはお菓子の話をしている場合は、その一つのファイルには、お菓子の特定の一種であり、赤いものは、それが意味するだろう、などイチゴ、リンゴのような緑色のもののような味):特定の値を持つセルの列と行のラベルを取得する

 
Candy Q  red  green  blue 
apple    X 
strawberry X 
smurf       X 
dunno lol X  X   X 

私はパンダのデータフレームにそれらをロードすることができ、それらを読み取って繰り返しますが、Xを含むセルの記述子を取得することはできませんでした。 パンダが提供する3つの異なるイテレータを試しましたが、取得する必要はありませんでした。私はイテレータを使用して、index-based value-checkingのインクリメントを試しましたが、かなり混乱してしまい、それを破棄しました。

出力は、{apple: green},{strawberry: red}, {smurf: blue},{dunno lol: [red, green, blue]}が理想的です。

どうすればこれらを得ることができますか?references

編集:追加する必要がある可能性があります:列や行の名前が一様ではないため、特定のロジックに従いますが、一般的に厳密なスキーマは定義できません。

更新#2:coldspeedとスコット・ボストン(プラス小さな修正)の組み合わせのソリューションごとのようにコード、:

files = glob.glob(mappings_path + '\\*.csv') 
# iterate over the list getting each file 
for file in files: 
    # open each file 
    with open(file,'r') as f: 
     # read content into pandas dataframe 
     df = pd.read_csv(f, delimiter=";", encoding='utf-8') 
     # set index to first column (and only column) 
     df = df.set_index(df.iloc[:, 0]) 

     d = defaultdict(list) 
     for x, y in zip(*np.where(df.notnull())): 
      d[df.index[x]].append(df.columns[y]) 

     res = dict(d) 
     for k, v in res.items(): 
      del v[0] 
     logger.info(res) 

記述の問題を修復し(例ではCandy Q)が最初に上げすべての結果リストで: {'apple': ['Candy Q','green'], 'strawberry': ['Candy Q','red']など。 Here's a link to the CSV files in case you need them or want to know what this is about、またはthe fourth download on this pageあなたがインターネット上のどこかに投稿者のリンクを信頼しない場合は、

ありがとうございました。

+0

あなたの現在のコードを表示 – RomanPerekhrest

+0

@RomanPerekhrest私はいくつかの可能性を見抜いて、それらが動作しない(または価値のあるものを作り出した)ものを捨てました。私は現在ファイルをロードしてiteritemsの結果を記録しています。振り出しに戻って。 – cmm

答えて

2

cᴏʟᴅsᴘᴇᴇᴅ@

{'apple': ['green'], 
'dunno lol': ['red', 'green', 'blue'], 
'smurf': ['blue'], 
'strawberry': ['red']} 

おかげで、私が編集し、簡素化を感謝しています。

+0

Psst、 'dunno lol'は3色のリストが必要です。 –

+0

ああ...私はそれを逃した。ありがとう。 –

+0

@cᴏʟᴅsᴘᴇᴇᴅあなたはPythonのほうがはるかに優れています。デフォルトのdictを使ってそれをきれいにすることはできますか? –

2
df 

     Candy Q red green blue 
0  apple NaN  X NaN 
1 strawberry X NaN NaN 
2  smurf NaN NaN X 
3 dunno lol X  X X 

df = df.set_index('Candy Q') 

少しハックが、本当に速いです。

j = df.notnull()\ 
     .dot(df.columns + '_')\ 
     .str.strip('_')\ 
     .str.split('_')\ 
     .to_dict() 

print(j) 
{ 
    "dunno lol": [ 
     "red", 
     "green", 
     "blue" 
    ], 
    "smurf": [ 
     "blue" 
    ], 
    "strawberry": [ 
     "red" 
    ], 
    "apple": [ 
     "green" 
    ] 
} 

これは、(セルXを有しているか否かを指定する)の列とマスクとの間の「ドット」製品を実行することを含みます。

ここで注意しなければならないのは、列名(この場合はアンダースコア)に列名として使用する区切り記号が列名の一部として存在しないことです。その場合は、列に存在しない区切り記号を選択してください。これは機能するはずです。

  red green blue 
Candy Q     
apple  NaN  X NaN 
strawberry X NaN NaN 
smurf  NaN NaN X 
dunno lol  X  X X 

あなたはインデックスを返すためにnp.whereを使用することができます:

from collections import defaultdict 

d = defaultdict(list) 
for x, y in zip(*np.where(df.notnull())): 
    d[df.index[x]].append(df.columns[y]) 

dict(d) 

出力:DFは

関連する問題