2014-01-11 3 views
8

В R, при добавлении новых данных неравной длины кадра данных, значения повторить, чтобы заполнить кадр данных:Как заполнить строки повторяющимися данными в пандах?

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

получают:

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

Однако панды требует равной длины индекса.

Как «заполнить» повторяющиеся данные в пандах, как я могу в R?

ответ

5

Похоже, что нет элегантного способа. Это обходной путь, который я только что понял. В основном создайте повторяющийся список, который больше, чем оригинальный фреймворк данных, а затем присоедините их к ним.

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. Мне нравится этот подход. –

2

Как вы можете найти общий вариант решения? Я попытался сделать это немного менее жестко закодированным:

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

Обратите внимание, что присвоение второго столбца имеет только 3 (не 6) значения. – Arun

+0

«Повторяющиеся данные» не являются повторяющимися столбцами. – Amyunimus

+0

whoops @Amyunimus Просмотреть меня редактирует. –

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 

Не особенно красивая, но одна «особенность» он обладает в том, что вам не придется беспокоиться, если длина DataFrame кратна длине повторяющиеся значения. np.put повторяет значения по мере необходимости.


Мой первый ответ был:

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

, но оказывается, что это значительно медленнее:

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

Это хорошо - хотя в моем конкретном случае я не хочу, чтобы цифры заполнялись, если они не «соответствуют» длине, а +1 для более общей полезности. – Amyunimus

0

В моем случае мне нужно повторить значения, не зная длину из суб-список, т. е. проверку длины каждой группы. Это было мое решение:

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

Метод цикла из itertools хорош для повторения общей схемы.

from itertools import cycle 

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

pythonic. +1 проголосовали ... – su79eu7k

Смежные вопросы