2017-08-02 83 views
6

ı değerler listesi var diyelim, df:Tamamlanmamış pandalar veri listesi, bir listedeki değer çiftlerinin ikili kombinasyonlarından nasıl verimli bir şekilde doldurulur? Ayrıca formun bir pandalar dataframe var</p> <pre><code>lst=['orange','apple','banana', 'grape', 'lemon'] </code></pre> <p>

Source  Destination  Weight 
orange  apple   0.4 
banana  orange   0.67 
grape  lemon   0.1 
grape  banana   0.5 

satırlar lst tüm ikili kombinasyonların bir alt grubudur. Her kombinasyonun en fazla bir kez göründüğünü unutmayın.

Source  Destination  Weight 
orange  apple   0.4 
banana  orange   0.67 
grape  lemon   0.1 
grape  banana   0.5 
orange  grape   0.0 
orange  lemon   0.0 
banana  lemon   0.0 

bir fark yapmaz sırası: Benim istediğim

kalan kombinasyonlar Örneğin 0.

, new_df değeriyle doldurulur yeni dataframe olduğunu.

Bunu yapmanın hızlı bir yolu nedir?

cevap

5
  • Zaten ben olanları bulmak için np.in1d kullanmak
  • mevcut kombinasyonlar için aynı şey
  • Sonra ekleme yoktur do
  • Sonra
  • kombinasyonları setlerinin bir dizi oluşturmak Henüz mevcut olmayanlarla yeni veri ağı.

from itertools import combinations 

comb = np.array([set(x) for x in combinations(lst, 2)]) 
exst = df[['Source', 'Destination']].apply(set, 1).values 
new = comb[~np.in1d(comb, exst)] 

d1 = pd.DataFrame(
    [list(x) for x in new], 
    columns=['Source', 'Destination'] 
).assign(Weight=0.) 

df.append(d1, ignore_index=True) 

    Source Destination Weight 
0 orange  apple 0.40 
1 banana  orange 0.67 
2 grape  lemon 0.10 
3 grape  banana 0.50 
4 grape  orange 0.00 
5 orange  lemon 0.00 
6 apple  banana 0.00 
7 grape  apple 0.00 
8 apple  lemon 0.00 
9 banana  lemon 0.00 
+0

Belki, gitmek orijinal yapıya geri döndür. Bir cevap aşağı almak sonra daha fazla arama ... şimdi arıyorum (-: – piRSquared

+0

Cevap için teşekkürler! Bunu yaparak çiftler aldığımızı fark ediyorum. Örneğin, muz/portakal 0.67 bir değer vardı, ama başka bir satır-turuncu/banana, 0.0 değeri ile eklenir. Bu satırları eklememenin bir yolu var mı? – Melsauce

+0

@Melsauce Bunu düşünmüyordum bile ... Düzeltmek veya farklı bir şeyle gelmek zorundayım. Birkaç dakika. – piRSquared

2

Adım 1: frozenset için kaynak dataframe dönüştürün

In [350]: df = df.assign(Combinations=df.apply(lambda x: frozenset(x[:-1]), axis=1)).loc[:, ['Combinations', 'Weight']] 

Adım 2: lst

In [352]: new_df = pd.DataFrame(list(itertools.combinations(lst, 2)), columns=['Source', 'Destination']) 
öğelerin ( import itertools önce) tüm olası kombinasyonları oluşturmak

Adım 3: Kombinasyonları birleştir

In [358]: new_df = new_df.iloc[:, :2].apply(lambda x: frozenset(x), axis=1)\ 
         .to_frame().rename(columns={0 : "Combinations"})\ 
         .merge(df, how='outer').fillna(0) 

Adım 4: beynim beni nereye götürürse

In [365]: new_df.apply(lambda x: pd.Series(list(x['Combinations'])), axis=1)\ 
       .rename(columns={0 : 'Source', 1 : 'Destination'})\ 
       .join(new_df['Weight']) 
Out[365]: 
    Source Destination Weight 
0 orange  apple 0.40 
1 orange  banana 0.67 
2 grape  orange 0.00 
3 orange  lemon 0.00 
4 apple  banana 0.00 
5 grape  apple 0.00 
6 apple  lemon 0.00 
7 grape  banana 0.50 
8 lemon  banana 0.00 
9 grape  lemon 0.10 
+0

Benimki gibi aynı sorun ... OP, '(' portakal ',' elma ') 've' (' elma ',' portakal ') ' – piRSquared

+0

@piRSquared arasındaki ilgisizliği istiyor Şimdi nasıl olur? Mermiyi ısırmak zorunda kaldım, bu gerçekten çok uzun sarıldı –

+0

Muza ne oldu, portakal rengi .67 – piRSquared