假设我有两个数据帧:
>> df1
0 1 2
0 a b c
1 d e f
>> df2
0 1 2
0 A B C
1 D E F
如何交错行?即获取此信息:
>> interleaved_df
0 1 2
0 a b c
1 A B C
2 d e f
3 D E F
(注意我的真实DF具有相同的列,但行数不同)。
受this question的启发(非常相似,但要求列):
import pandas as pd
from itertools import chain, zip_longest
df1 = pd.DataFrame([['a','b','c'], ['d','e','f']])
df2 = pd.DataFrame([['A','B','C'], ['D','E','F']])
concat_df = pd.concat([df1,df2])
new_index = chain.from_iterable(zip_longest(df1.index, df2.index))
# new_index now holds the interleaved row indices
interleaved_df = concat_df.reindex(new_index)
ValueError: cannot reindex from a duplicate axis
最后一次调用失败,因为df1和df2有一些相同的索引值(我的真实DF也是如此)。
有什么想法吗?
答案 0 :(得分:11)
您可以在连接后对索引进行排序,然后重置索引,即
import pandas as pd
df1 = pd.DataFrame([['a','b','c'], ['d','e','f']])
df2 = pd.DataFrame([['A','B','C'], ['D','E','F']])
concat_df = pd.concat([df1,df2]).sort_index().reset_index(drop=True)
输出:
0 1 2 0 a b c 1 A B C 2 d e f 3 D E F
编辑(OmerB):无论指数值如何,都要保持秩序。
import pandas as pd
df1 = pd.DataFrame([['a','b','c'], ['d','e','f']]).reset_index()
df2 = pd.DataFrame([['A','B','C'], ['D','E','F']]).reset_index()
concat_df = pd.concat([df1,df2]).sort_index().set_index('index')
答案 1 :(得分:4)
使用toolz.interleave
In [1024]: from toolz import interleave
In [1025]: pd.DataFrame(interleave([df1.values, df2.values]))
Out[1025]:
0 1 2
0 a b c
1 A B C
2 d e f
3 D E F
答案 2 :(得分:1)
这里是@Bharath答案的扩展,可以使用pd.MultiIndex
应用于具有用户定义的索引的DataFrame,而不会丢失它们。
使用完整的列/索引标签和名称定义数据框:
df1 = pd.DataFrame([['a','b','c'], ['d','e','f']], index=['one', 'two'], columns=['col_a', 'col_b','col_c'])
df1.columns.name = 'cols'
df1.index.name = 'rows'
df2 = pd.DataFrame([['A','B','C'], ['D','E','F']], index=['one', 'two'], columns=['col_a', 'col_b','col_c'])
df2.columns.name = 'cols'
df2.index.name = 'rows'
将DataFrame ID添加到MultiIndex:
df1.index = pd.MultiIndex.from_product([[1], df1.index], names=["df_id", df1.index.name])
df2.index = pd.MultiIndex.from_product([[2], df2.index], names=["df_id", df2.index.name])
然后使用@Bharath的concat()
和sort_index()
:
data = pd.concat([df1, df2], axis=0, sort=True)
data.sort_index(axis=0, level=data.index.names[::-1], inplace=True)
输出:
cols col_a col_b col_c
df_id rows
1 one a b c
2 one A B C
1 two d e f
2 two D E F
答案 3 :(得分:0)
您可以尝试这种方式:
In [31]: from toolz import interleave
...: import pandas as pd
...: from itertools import chain, zip_longest
...:
...: df1 = pd.DataFrame([['a','b','c'], ['d','e','f']])
...: df2 = pd.DataFrame([['A','B','C'], ['D','E','F']])
In [32]: concat_df = pd.concat([df1,df2]).sort_index()
...:
In [33]: interleaved_df = concat_df.reset_index(drop=1)
In [34]: interleaved_df
Out[34]:
0 1 2
0 a b c
1 A B C
2 d e f
3 D E F
答案 4 :(得分:0)
您还可以预先分配新的export XDEBUG_CONFIG="idekey=PHPSTORM"
,然后使用切片填充它。
DataFrame
预分配代码取自this question。
虽然对于某些数据类型/大小,它有可能胜过索引方法,但如果DataFrame具有不同的大小,它将无法正常运行。
注意 - 对于具有20列混合字符串,整数和浮动类型的~200000行,索引方法快约5倍。