2016-04-20 2 views
1

у меня есть два dataFrames, откуда извлечь уникальные значения столбца в и бРегистрация уникальных значений в новый кадр данных (питон, панды)

a = df1.col1.unique() 
b = df2.col2.unique() 

теперь и б что-то вроде этого

['a','b','c','d'] #a 
[1,2,3] #b 

они теперь типа numpy.ndarray

Я хочу присоединиться к ним, чтобы иметь DataFrame как этот

col1 col2 
0 a  1 
1 a  2 
3 a  3 
4 b  1 
5 b  2 
6 b  3 
7 c  1 
    . . . 

Есть ли способ сделать это, не используя петлю?

+0

Является ли понимание списка приемлемым? –

+0

Мне нужно, чтобы это было DataFrame –

+0

@RoseAlejandra - Нет, я спрашиваю, приемлемо ли понимание списка для создания DataFrame. Вы говорите без цикла «for», которые перечислены в контекстах неявно, но не явно. –

ответ

0

UPDATE:

решение с использованием NumPy BM является гораздо быстрее - я бы рекомендовал использовать его подход:

In [88]: %timeit pd.DataFrame({'col1':np.repeat(aa,bb.size),'col2':np.tile(bb,aa.size)}) 
10 loops, best of 3: 25.4 ms per loop 

In [89]: %timeit pd.DataFrame(list(product(aa,bb)), columns=['col1', 'col2']) 
1 loop, best of 3: 1.28 s per loop 

In [90]: aa.size 
Out[90]: 1000 

In [91]: bb.size 
Out[91]: 1000 

попробовать itertools.product:

In [56]: a 
Out[56]: 
array(['a', 'b', 'c', 'd'], 
     dtype='<U1') 

In [57]: b 
Out[57]: array([1, 2, 3]) 

In [63]: pd.DataFrame(list(product(a,b)), columns=['col1', 'col2']) 
Out[63]: 
    col1 col2 
0  a  1 
1  a  2 
2  a  3 
3  b  1 
4  b  2 
5  b  3 
6  c  1 
7  c  2 
8  c  3 
9  d  1 
10 d  2 
11 d  3 
+0

Так как 'itertools.product (a, b)' возвращает итератор, состоящий из кортежей, я подозреваю дополнительное понимание списка для '[[x [0], x [1]]' было ненужным. –

+0

@AkshatMahajan, спасибо! Я тоже это понял :) – MaxU

0

Вы можете» t выполните эту задачу, не используя, по крайней мере, один цикл. Лучшее, что вы можете сделать, это скрыть цикл for или использовать неявные звонки yield, чтобы сделать генератор с эффективной памятью.

itertools экспортирует эффективные функции для решения этой задачи, которые используют yield неявно для возврата генераторов:

from itertools import product 

products = product(['a','b','c','d'], [1,2,3]) 

col1_items, col2_items = zip(*products) 

result = pandas.DataFrame({'col1':col1_items, 'col2': col2_items}) 

itertools.product создает Cartesian product два итерируемых. zip(*products) просто распаковывает полученный список кортежей в два отдельных набора, как видно here.

0

Вы можете сделать это с панды слияния и это будет быстрее, чем itertools или цикл:

df_a = pd.DataFrame({'a': a, 'key': 1}) 
df_b = pd.DataFrame({'b': b, 'key': 1}) 
result = pd.merge(df_a, df_b, how='outer') 

результат:

a key b 
0 a 1 1 
1 a 1 2 
2 a 1 3 
3 b 1 1 
4 b 1 2 
5 b 1 3 
6 c 1 1 
7 c 1 2 
8 c 1 3 
9 d 1 1 
10 d 1 2 
11 d 1 3 

затем, если требуется, вы всегда можете сделать

del result['key'] 
1

с numpy tools:

pd.DataFrame({'col1':np.repeat(a,b.size),'col2':np.tile(b,a.size)}) 
+0

Очень приятное решение! – MaxU

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