2014-11-06 23 views
16

Chcę replikować wiersze w ramce danych Pandas. Każdy wiersz należy powtórzyć n razy, gdzie n jest polem w każdym rzędzie.Replikowanie wierszy w ramce danych pandy według wartości kolumny

import pandas as pd 

what_i_have = pd.DataFrame(data={ 
    'id': ['A', 'B', 'C'], 
    'n' : [ 1, 2, 3], 
    'v' : [ 10, 13, 8] 
}) 

what_i_want = pd.DataFrame(data={ 
    'id': ['A', 'B', 'B', 'C', 'C', 'C'], 
    'v' : [ 10, 13, 13, 8, 8, 8] 
}) 

Czy to możliwe?

+0

Czy jest jakiś powód, aby to zrobić? Myślę, że najlepiej jest unikać powielania danych. – greole

+0

Cóż, jest to etap pośredni - generuję kolumnę "v" zgodnie z rozkładem prawdopodobieństwa, a następnie dodaję kolejną kolumnę, losowo wybierając wiersze z innego zestawu danych. –

+0

Nadal nie widzę powodu, aby nie robić tego bezpośrednio. Ale potrzebowałbym więcej informacji na temat tego, co faktycznie próbujesz osiągnąć. – greole

Odpowiedz

27

Można użyć np.repeat uzyskać powtarzające indeksy, a następnie użyć jej do indeksu w ramce:

>>> df2 = df.loc[np.repeat(df.index.values,df.n)] 
>>> df2 
    id n v 
0 A 1 10 
1 B 2 13 
1 B 2 13 
2 C 3 8 
2 C 3 8 
2 C 3 8 

Po której jest tylko trochę czyszczenia zrobić:

>>> df2 = df2.drop("n",axis=1).reset_index(drop=True) 
>>> df2 
    id v 
0 A 10 
1 B 13 
2 B 13 
3 C 8 
4 C 8 
5 C 8 

Note Jeśli możesz mieć zdublowane indeksy, o które musisz się martwić, możesz zamiast tego użyć numeru .iloc:

In [86]: df.iloc[np.repeat(np.arange(len(df)), df["n"])].drop("n", axis=1).reset_index(drop=True) 
Out[86]: 
    id v 
0 A 10 
1 B 13 
2 B 13 
3 C 8 
4 C 8 
5 C 8 

, która używa pozycji, a nie etykiet indeksu.

+2

W nowszej wersji może to być 'df.loc [df.index.repeat (df.n)]' – Zero

2

Można użyć set_index i repeat

In [1057]: df.set_index(['id'])['v'].repeat(df['n']).reset_index() 
Out[1057]: 
    id v 
0 A 10 
1 B 13 
2 B 13 
3 C 8 
4 C 8 
5 C 8 

Szczegóły

In [1058]: df 
Out[1058]: 
    id n v 
0 A 1 10 
1 B 2 13 
2 C 3 8 
Powiązane problemy