我有一个DataFrame
,看起来像这样:
id t_l
0 100 [('a', 1), ('b', 2)]
1 151 [('x', 4), ('y', 3)]
我需要返回一个DataFrame
,如下所示:
id f g
0 100 'a' 1
1 'b' 2
2 151 'x' 4
3 'y' 3
最好的方法是什么?
答案 0 :(得分:2)
修改:
@ALollz很好地说明了np.concatenate
与chain.from_iterable(df.t_l)
的速度。我%timeit
,这是真的。因此,我使用from_iterable(df.t_l)
from itertools import chain
pd.DataFrame(chain.from_iterable(df.t_l), index=np.repeat(df.id, df.t_l.str.len()), \
columns=['f', 'g']).reset_index()
原始:
我将使用df
作为数据和np.concatenate
作为索引来构造一个新的np.repeat
。最后,reset_index
将id
返回到列
pd.DataFrame(np.concatenate(df.t_l), index=np.repeat(df.id, df.t_l.str.len()), \
columns=['f', 'g']).reset_index()
Out[596]:
id f g
0 100 a 1
1 100 b 2
2 151 x 4
3 151 y 3
答案 1 :(得分:1)
df.set_index('id').apply(lambda x: pd.Series([list(i) for i in list(x.t_l)]), axis=1).stack().apply(pd.Series).rename({0:'f',1:'g'}, axis=1).reset_index(level=1, drop=True)
OR ..删除pd.Series
方法以提高效率
pd.DataFrame(df.set_index('id').apply(lambda x: pd.Series([list(i) for i in list(x.t_l)]), axis=1).stack()).rename({0:'f',1:'g'}, axis=1).reset_index(level=1, drop=True)
输出
f g
id
100 a 1
100 b 2
151 x 4
151 y 3
答案 2 :(得分:1)
使用apply()
和pd.multiindex
:-
df = pd.DataFrame(data = [ [100, [('a', 1), ('b', 2)] ] , [151,[('x', 4), ('y', 3)]]
], columns=['id', 't_1'] )
inside, outside, value = [], [], []
c = 0
def get_outside(x):
global c
length = len( df['t_1'][c] )
c+=1
for var in range(length):
outside.append(x)
def get_inside_value(y):
for var in y:
inside.append(var[0])
value.append(var[1])
df['id'].apply(get_outside)
df['t_1'].apply(get_inside_value)
hier_index = list(zip(outside,inside))
hier_index = pd.MultiIndex.from_tuples(hier_index)
new_df = pd.DataFrame(value ,index=hier_index,columns=['g',])
new_df.index.names = ['id','f']
new_df
输出
g
id f
100 a 1
b 2
151 x 4
y 3
答案 3 :(得分:1)
对zip
使用嵌套列表理解:
zipped = zip(df['id'], df['t_l'])
df = pd.DataFrame([(i, y1, y2) for i, x in zipped for y1, y2 in x], columns=['id','f','g'])
print (df)
id f g
0 100 a 1
1 100 b 2
2 151 x 4
3 151 y 3
如果需要MultiIndex系列:
zipped = zip(df['id'], df['t_l'])
s = pd.Series({(i, y1):y2 for i, x in zipped for y1, y2 in x})
print (s)
100 a 1
b 2
151 x 4
y 3
dtype: int64
答案 4 :(得分:1)
new = pd.DataFrame(columns=['id','f','g'])
for ind, row in df.iterrows():
x, y = row
for i in range(len(y)):
(a,b) = y[i]
if i==0:
new.loc[str(ind)] = x,a,b
else:
new.loc[str(ind)+str(i)] = '',a,b
这将系统地解压缩t_1个元素,并以所需的结构输出数据框。
输出:
id f g
0 100 a 1
01 b 2
1 151 x 4
11 y 3
警告:这是一种简单的方法,但是如果用于大量数据,则成本可能会大大增加。