2016-07-26 3 views
4

У меня есть два dataframes следующим образом:Панды конкатенации чередующиеся столбцы

df2 = pd.DataFrame(np.random.randn(5,2),columns=['A','C']) 
df3 = pd.DataFrame(np.random.randn(5,2),columns=['B','D']) 

Я хочу, чтобы получить столбцы чередуясь таким образом, что я получаю результат ниже:

df4 = pd.DataFrame() 
for i in range(len(df2.columns)): 
    df4[df2.columns[i]]=df2[df2.columns[i]] 
    df4[df3.columns[i]]=df3[df3.columns[i]] 

df4 

    A B C D 
0 1.056889 0.494769 0.588765 0.846133 
1 1.536102 2.015574 -1.279769 -0.378024 
2 -0.097357 -0.886320 0.713624 -1.055808 
3 -0.269585 -0.512070 0.755534 0.855884 
4 -2.691672 -0.597245 1.023647 0.278428 

Я думаю, что я» m действительно неэффективен с этим решением. Чем больше pythonic/pandic способ сделать это?

p.s. В моем конкретном случае имена столбцов не A, B, C, D и не расположены в алфавитном порядке. Просто знайте, какие два кадра данных я хочу объединить.

+3

Hah, _ ~ pandic ~ _. – miradulo

+0

Сколько столбцов находится в обоих кадрах данных с реальными данными? – jezrael

+0

Число столбцов равно, скажем 2 сейчас. –

ответ

7

Если вам нужно что-то более динамичным, первый почтовый индекс обе колонки имена обоих DataFrames, а затем плоский его:

df5 = pd.concat([df2, df3], axis=1) 
print (df5) 
      A   C   B   D 
0 0.874226 -0.764478 1.022128 -1.209092 
1 1.411708 -0.395135 -0.223004 0.124689 
2 1.515223 -2.184020 0.316079 -0.137779 
3 -0.554961 -0.149091 0.179390 -1.109159 
4 0.666985 1.879810 0.406585 0.208084 

#http://stackoverflow.com/a/10636583/2901002 
print (list(sum(zip(df2.columns, df3.columns),()))) 
['A', 'B', 'C', 'D'] 
print (df5[list(sum(zip(df2.columns, df3.columns),()))]) 
      A   B   C   D 
0 0.874226 1.022128 -0.764478 -1.209092 
1 1.411708 -0.223004 -0.395135 0.124689 
2 1.515223 0.316079 -2.184020 -0.137779 
3 -0.554961 0.179390 -0.149091 -1.109159 
4 0.666985 0.406585 1.879810 0.208084 
+0

Я понимаю, что zip помещает имена столбцов таким образом, что вы получаете '[('A', 'B'), ('C', 'D')]', и я вижу, что сделала 'sum' , но можете ли вы объяснить, что сделала 'sum'? Особенно сложно понять, почему этот пустой кортеж '()' помогает с расширением этого zipped-массива –

+0

Это просто суммирует элементы итерабеля, переданные в первом аргументе, обрабатывая второй аргумент как начальное значение суммы (если не указано, 0 является используется вместо этого, и этот случай даст вам ошибку). Таким образом, вывод - 'tuple' -' ('A', 'B', 'C', 'D') ', который преобразуется в' list'. – jezrael

2

Как насчет этого?

df4 = pd.concat([df2, df3], axis=1) 

Или они должны быть в определенном порядке? Во всяком случае, вы всегда можете изменить их порядок:

df4 = df4[['A','B','C','D']] 

И не выписывая столбцы:

df4 = df4[[item for items in zip(df2.columns, df3.columns) for item in items]] 
+1

_ «Я хочу получить столбцы чередующимся образом». Итак, один из первого столбца, за которым следует один из второго столбца, затем второй из первого столбца и т. Д. – miradulo

+0

@Mitch Gotcha, добавленный немного по переупорядочиванию колонны. – kloffy

+0

Это решение, но я думаю, что речь идет не о том, чтобы я писал имена столбцов, чтобы иметь возможность поочередно получать столбцы. –

1

Append даже индексы к df2 столбцов и нечетных индексов к df3 столбцов. Используйте эти новые уровни для сортировки.

df2_ = df2.T.set_index(np.arange(len(df2.columns)) * 2, append=True).T 
df3_ = df3.T.set_index(np.arange(len(df3.columns)) * 2 + 1, append=True).T 

df = pd.concat([df2_, df3_], axis=1).sort_index(1, 1) 
df.columns = df.columns.droplevel(1) 

df 

enter image description here

2

concat Вы могли бы затем reindex_axis.

df = pd.concat([df2, df3], axis=1) 
df.reindex_axis(df.columns[::2].tolist() + df.columns[1::2].tolist(), axis=1) 
Смежные вопросы