2015-09-26 14 views
7

Bir veri işlem çerçevem ​​var. Her satır iki öğenin bir işlemini temsil eder (2 etkinlik bileti veya benzeri bir işlem gibi düşünün). Satılan miktara göre her satırı çoğaltmak istiyorum. Bu yüzden yukarıdaki durumda, her bir satır iki yinelenen satırlar dönüşecek buFarklı sütunlardaki değere göre yinelenen satır

Price City Quantity 

20  NYC   2 

30  NYC   2 

5  NYC   2 

300  LA   2 

30  LA   2 

100  LA   2 

gibi görünen bir dataframe üretir

# dictionary of transactions 

d = {'1': ['20', 'NYC', '2'], '2': ['30', 'NYC', '2'], '3': ['5', 'NYC', '2'], \ 
    '4': ['300', 'LA', '2'], '5': ['30', 'LA', '2'], '6': ['100', 'LA', '2']} 

columns=['Price', 'City', 'Quantity'] 

# create dataframe and rename columns 

df = pd.DataFrame.from_dict(data=d, orient='index') 
df.columns = columns 

:

İşte örnek kod. 'Miktar' sütunu 3 ise, o satır üç kopya satır haline dönüşür.

+0

http://stackoverflow.com

df.iloc[:,2:] = a 

ve şimdi df biz Miktar sayıyı geçen sıfır olarak ayarlanır nasıl fark aşağıdaki gibi görünür/help/mcve - bunun için yazdığınız kod nerede ve hangi çıktı * siz * aldınız? İstediğiniz çıktıyı yeterince iyi tanımladınız, ancak bunun içinde StackOverflow sorusu yok gibi görünüyor. Unutmayın ki kod için * kodlama * kod tasarımı ve yazma değildir. – Prune

+0

@Prune Ben katılmıyorum, bu belirli bir programlama probleminin açıklamasına uyuyor gibi görünüyor. OP, bu problemi çözmek için etkili bir yol belirlemede bazı rehberlik kullanabilir. Bazen bir kişi nereden başlayacağını bile bilmez ve bir çözümde çirkin bir girişimi soruyu çözer ve herkesin zamanını boşa harcar. –

+0

@ Prune'un tavsiyesine minnettarım ve genelde buna katılıyorum. Bence bu tamamen tembel soruları filtrelemek için iyi bir yol. Bu sorun beni güldürdü ve bir çözüm için anlamlı bir başlangıç ​​noktası sağlayamadım. – MRA

cevap

6

İlk olarak, verilerinizi metin yerine tamsayılar kullanarak yeniden oluşturdum. Ben de miktarı daha kolay anlayabilmem için miktarı değiştirdim.

d = {1: [20, 'NYC', 1], 2: [30, 'NYC', 2], 3: [5, 'SF', 3],  
    4: [300, 'LA', 1], 5: [30, 'LA', 2], 6: [100, 'SF', 3]} 

columns=['Price', 'City', 'Quantity'] 
# create dataframe and rename columns 

df = pd.DataFrame.from_dict(data=d, orient='index').sort_index() 
df.columns = columns 

>>> df 
    Price City Quantity 
1  20 NYC   1 
2  30 NYC   2 
3  5 SF   3 
4 300 LA   1 
5  30 LA   2 
6 100 SF   3 

Yuvalanmış liste anlama yapısı kullanarak yeni bir DataFrame oluşturdum.

df_new = pd.DataFrame([df.ix[idx] 
         for idx in df.index 
         for _ in range(df.ix[idx]['Quantity'])]).reset_index(drop=True) 
>>> df_new 
    Price City Quantity 
0  20 NYC   1 
1  30 NYC   2 
2  30 NYC   2 
3  5 SF   3 
4  5 SF   3 
5  5 SF   3 
6  300 LA   1 
7  30 LA   2 
8  30 LA   2 
9  100 SF   3 
10 100 SF   3 
11 100 SF   3 
+0

Teşekkürler. Gerçek verilerimde denediğimde, "TypeError: serisini 'a dönüştüremiyorum" ifadesini "for the range" ile ilgili "for _ in range" (df.ix [idx] ['Quantity']) "ile ilgili. – MRA

+0

Bunu deneyin: _ için aralıkta (int (df.ix [idx] ['Miktar'])) 'Ayrıca sütunu tamsayılara açıkça dönüştürebilirsiniz: df ['Miktar'] = dfQuantity.astype (int) – Alexander

+0

Aynı hatayı alıyorum. – MRA

2

Bu yaklaşım nasıl yapılır? Verilerinizi 4 bilet satışı yapmak için biraz değiştirdim. Then, sadece bir çağrı numpy - update values using slicing given an array value

: burada, bu teknik gösterilmiştir a[np.arange(a.shape[1])[:] > a[:,0,np.newaxis]] = 0

:

Bir yardımcı np.ones() dizi, uygun büyüklükte ve daha sonra bir kod anahtarı hattı kullanmak .stack() ve tamamlanması için bazı temel filtreleme. benziyor

d = {'1': ['20', 'NYC', '2'], '2': ['30', 'NYC', '2'], '3': ['5', 'NYC', '2'], \ 
    '4': ['300', 'LA', '2'], '5': ['30', 'LA', '4'], '6': ['100', 'LA', '2']} 

columns=['Price', 'City', 'Quantity'] 
df = pd.DataFrame.from_dict(data=d, orient='index') 
df.columns = columns 
df['Quantity'] = df['Quantity'].astype(int) 

# make a ones array 
my_ones = np.ones(shape=(len(df),df['Quantity'].max())) 

# turn my_ones into a dataframe same index as df so we can join it to the right hand side. Plenty of other ways to achieve the same outcome. 
df_my_ones = pd.DataFrame(data =my_ones,index = df.index) 

df = df.join(df_my_ones) 

:

Price City Quantity 0 1 2 3 
1 20 NYC   2 1 1 1 1 
3  5 NYC   2 1 1 1 1 
2 30 NYC   2 1 1 1 1 
5 30 LA   4 1 1 1 1 
4 300 LA   2 1 1 1 1 

artık numpy diziye Miktar sütunu ve olanları almak

a = df.iloc[:,2:].values 

bu akıllı Biti olduğunu

a[np.arange(a.shape[1])[:] > a[:,0,np.newaxis]] = 0 

ve df'ye yeniden atayın.

Price City Quantity 0 1 2 3 
1 20 NYC   2 1 1 0 0 
3  5 NYC   2 1 1 0 0 
2 30 NYC   2 1 1 0 0 
5 30 LA   4 1 1 1 1 
4 300 LA   2 1 1 0 0 

df.set_index(['Price','City','Quantity'],inplace=True) 
df = df.stack().to_frame() 
df.columns = ['sale_flag'] 
df.reset_index(inplace=True) 
print df[['Price','City', 'Quantity']][df['sale_flag'] !=0] 
print df 

üretir:

Price City Quantity 
0  20 NYC   2 
1  20 NYC   2 
4  5 NYC   2 
5  5 NYC   2 
8  30 NYC   2 
9  30 NYC   2 
12 30 LA   4 
13 30 LA   4 
14 30 LA   4 
15 30 LA   4 
16 300 LA   2 
17 300 LA   2 
+0

Çok yaratıcı bir çözüm! Daha dikkatli bir şekilde incelemek zorundayım. Farklı bir yaklaşım için aşağıdaki diğer yanıtı da kontrol edin. Yardımınız için çok fazla. – MRA

İlgili konular