2014-01-11 13 views
8

In R, wenn neue Daten von ungleicher Länge zu einem Datenrahmen hinzuzufügen, wiederholen sich die Werte des Datenrahmens zu füllen:Wie füllt man Zeilen mit sich wiederholenden Daten in Pandas?

df <- data.frame(first=c(1,2,3,4,5,6)) 
df$second <- c(1,2,3) 

Nachgeben:

first second 
1  1  1 
2  2  2 
3  3  3 
4  4  1 
5  5  2 
6  6  3 

jedoch pandas erfordert gleich Indexlängen.

Wie kann ich "wiederholen" Daten in Pandas wie ich in R?

Antwort

5

Scheint, es gibt keine elegante Art und Weise. Dies ist die Problemumgehung, die ich gerade herausgefunden habe. Im Grunde erstellen Sie eine Wiederholungsliste, die nur größer als der ursprüngliche Datenrahmen ist, und schließen Sie sie dann an.

import pandas 
df = pandas.DataFrame(range(100), columns=['first']) 
repeat_arr = [1, 2, 3] 
df = df.join(pandas.DataFrame(repeat_arr * (len(df)/len(repeat_arr)+1), 
    columns=['second'])) 
+0

+1. Ich mag diesen Ansatz. –

2

Wie allgemein für eine Lösung suchen Sie? Ich versuchte, dies ein wenig weniger hart-codiert machen:

import numpy as np 
import pandas 

df = pandas.DataFrame(np.arange(1,7), columns=['first']) 

base = [1, 2, 3] 
df['second'] = base * (df.shape[0]/len(base)) 
print(df.to_string()) 


    first second 
0  1  1 
1  2  2 
2  3  3 
3  4  1 
4  5  2 
5  6  3 
+1

Beachten Sie, dass die 2. Spaltenzuordnung nur 3 (nicht 6) Werte hat. – Arun

+0

Die "wiederholten Daten" sind keine doppelten Spalten. – Amyunimus

+0

whoops @Amyunimus Sieh mir Änderungen. –

2
import pandas as pd 
import numpy as np 

def put(df, column, values): 
    df[column] = 0 
    np.put(df[column], np.arange(len(df)), values) 

df = pd.DataFrame({'first':range(1, 8)})  
put(df, 'second', [1,2,3]) 

first second 
0  1  1 
1  2  2 
2  3  3 
3  4  1 
4  5  2 
5  6  3 
6  7  1 

Nicht besonders schön, aber ein „Feature“ ergibt es besitzt, ist, dass Sie sich keine Sorgen machen, wenn die Länge des Datenrahmens ist ein Vielfaches der Länge die wiederholten Werte. np.put wiederholt die Werte wie erforderlich.


Meine erste Antwort war:

import itertools as IT 
df['second'] = list(IT.islice(IT.cycle([1,2,3]), len(df))) 

aber es stellt sich heraus, das ist deutlich langsamer:

In [312]: df = pd.DataFrame({'first':range(10**6)}) 

In [313]: %timeit df['second'] = list(IT.islice(IT.cycle([1,2,3]), len(df))) 
10 loops, best of 3: 143 ms per loop 

In [316]: %timeit df['second'] = 0; np.put(df['second'], np.arange(N), [1,2,3]) 
10 loops, best of 3: 27.9 ms per loop 
+0

Das ist nett - obwohl ich in meinem speziellen Fall nicht möchte, dass die Zahlen ausgefüllt werden, wenn sie nicht die Länge "passen", sondern +1 für allgemeineren Nutzen. – Amyunimus

0

In meinem Fall musste ich die Werte wiederholen, ohne die Länge der wissen Unterliste, dh Überprüfung der Länge jeder Gruppe. Dies war meine Lösung:

import numpy as np 
import pandas 

df = pandas.DataFrame(['a','a','a','b','b','b','b'], columns=['first']) 

list = df.groupby('first').apply(lambda x: range(len(x))).tolist() 
loop = [val for sublist in list for val in sublist] 
df['second']=loop 

df 
    first second 
0  a  0 
1  a  1 
2  a  2 
3  b  0 
4  b  1 
5  b  2 
6  b  3 
3

Der Zyklus Methode von itertools ist gut für ein gemeinsames Muster zu wiederholen.

from itertools import cycle 

seq = cycle([1, 2, 3]) 
df['Seq'] = [next(seq) for count in range(df.shape[0])] 
+0

Python. +1 gewählt ... – su79eu7k

Verwandte Themen