2016-03-24 11 views
1

İki DataFrame'im var, biri 'recipe', malzemelerin birleşimi, diğeri ise "kombinasyonlar" gibi popüler kombinasyonları içeriyor.Etiketler python pandas.Dataframe'deki bir listeye göre nasıl atanır?

kombinasyonu 'gibi' listelenen eğer

nasıl, reçeteye bir sütun 'C' ekleyebilir

recipe = pd.DataFrame({'A': ['chicken','beef','pork','egg', 'chicken', 'egg', 'beef'], 
         'B': ['sweet', 'hot', 'salty', 'hot', 'sweet', 'salty', 'hot']}) 
recipe 
    A  B 
0 chicken sweet 
1  beef hot 
2  pork salty 
3  egg hot 
4 chicken sweet 
5  egg salty 
6  beef hot 

like = pd.DataFrame({'A':['beef', 'egg'], 'B':['hot', 'salty']}) 
like 
    A  B 
0 beef hot 
1 egg salty 
, o zaman 'evet' ise 'hayır' o değer vermek ?

istediğim sonuç sorun benim hem dataframes büyük olduğunu

recipe 
     A  B C 
0 chicken sweet no 
1  beef hot yes 
2  pork salty no 
3  egg hot no 
4 chicken sweet no 
5  egg salty yes 
6  beef hot yes 

olduğunu. 'Beğenme' içindeki öğeleri manuel olarak seçemiyorum ve 'tarifi' içinde 'evet' etiketini atamam. Bunu yapmanın kolay yolu var mı?

+0

Örneğin 'A' öğeleri 'beef' olabilirdi, ancak 'B' içinde 'yanlış' bir uyumsuzluğa neden olur? – Leb

+0

@Leb, "A", "B", "tuzlu" ise, "hayır" etiketini atayacağım. Yanlış eşleşme olmaz. – xirururu

cevap

2

Sen merge ve numpy.where kullanabilirsiniz:

df = pd.merge(recipe, like, on=['A','B'], indicator=True, how='left') 
print df 
     A  B  _merge 
0 chicken sweet left_only 
1  beef hot  both 
2  pork salty left_only 
3  egg hot left_only 
4 chicken sweet left_only 
5  egg salty  both 
6  beef hot  both 

df['C'] = np.where(df['_merge'] == 'both', 'yes', 'no') 

print df[['A','B','C']] 
     A  B C 
0 chicken sweet no 
1  beef hot yes 
2  pork salty no 
3  egg hot no 
4 chicken sweet no 
5  egg salty yes 
6  beef hot yes 

hızlı kullanmak df['_merge'] == 'both' geçerli:

In [460]: %timeit np.where(np.in1d(df['_merge'],'both'), 'yes', 'no') 
100 loops, best of 3: 2.22 ms per loop 

In [461]: %timeit np.where(df['_merge'] == 'both', 'yes', 'no') 
1000 loops, best of 3: 652 µs per loop 
+0

Teşekkürler !!! Ben her zaman 'concat' ve 'join' hakkında düşünürüm. Ama çözümü bulamadı. 'Birleştirme' cevabı.: D – xirururu

1

Sen like için 'yes' s'lik bir C sütun ekleyin ve sonra like ile recipe birleştirebilir. Eşleşen satırlar, C sütununda yes sütununa sahip olacak, eşleşme olmadan satırlar NaN s olacaktır. Daha sonra 'no' s ile NaN'ler yerine fillna kullanabilirsiniz:

import pandas as pd 
recipe = pd.DataFrame({'A': ['chicken','beef','pork','egg', 'chicken', 'egg', 'beef'], 
         'B': ['sweet', 'hot', 'salty', 'hot', 'sweet', 'salty', 'hot']}) 

like = pd.DataFrame({'A':['beef', 'egg'], 'B':['hot', 'salty']}) 
like['C'] = 'yes' 
result = pd.merge(recipe, like, how='left').fillna('no') 
print(result) 

  A  B C 
0 chicken sweet no 
1  beef hot yes 
2  pork salty no 
3  egg hot no 
4 chicken sweet no 
5  egg salty yes 
6  beef hot yes 
1

Hem A ve B gibi eşleştirerek set_value kullanabilirsiniz verir:

recipe.set_value(recipe[recipe.A.isin(like.A) & recipe.B.isin(like.B)].index,'C','yes') 
recipe.fillna('no') 

Hangi olacak ver:

  A  B C 
0 chicken sweet no 
1  beef hot yes 
2  pork salty no 
3  egg hot yes 
4 chicken sweet no 
5  egg salty yes 
6  beef hot yes 

Not: Bu sonuçlar, yanıtın diğerlerinden daha iyi olduğu anlamına gelmez veya tersi de geçerlidir.

%timeit recipe.set_value(recipe[recipe.A.isin(like.A) & recipe.B.isin(like.B)].index,'C','yes'); recipe.fillna('no') 
100 loops, best of 3: 2.69 ms per loop 

merge kullanma ve yeni df oluşturarak: set_value kullanma

%timeit df = pd.merge(recipe, like, on=['A','B'], indicator=True, how='left'); df['C'] = np.where(df['_merge'] == 'both', 'yes', 'no') 
100 loops, best of 3: 8.42 ms per loop 

sadece merge kullanma:

%timeit df['C'] = np.where(df['_merge'] == 'both', 'yes', 'no') 
1000 loops, best of 3: 187 µs per loop 

Yine, bu gerçekten zamanlama olduğunuz şeye bağlıdır . Sadece verilerinizi kopyalamaktan çekinmeyin.

+2

set_value gerçek bir deyim değildir; sadece ödevi kullan. tarif ['C'] = ... – Jeff

+0

Bence bu kod da çok zekice. Ama hızın "birleştirme" ile kıyaslandığında ne düşünüyorsun? – xirururu

+0

@xirururu düzenlememi okuyun, her şey yinelenebileceğin kısma bağlıdır. – Leb

İlgili konular