我有一个看起来像这样的数据框:
df = pd.DataFrame(
{'tod': [[('a',10),('b',6),('h',3),('p',2)],
[('x',11),('e',2),('l',2)],
[('r',5),('l',5)],
[('n',15)]]})
tod
0 [(a, 10), (b, 6), (h, 3), (p, 2)]
1 [(x, 11), (e, 2), (l, 2)]
2 [(r, 5), (l, 5)]
3 [(n, 15)]
我想将元组列表扩展到新列以获得:
tod l1 n1 l2 n2 l3 n3 l4 n4
0 [(a, 10), (b, 6), (h, 3), (p, 2)] a 10 b 6 h 3 p 2
1 [(x, 11), (e, 2), (l, 2)] x 11 e 2 l 2 - nan
2 [(r, 5), (l, 5)] r 5 l 5 - nan - nan
3 [(n, 15)] n 15 - nan - nan - nan
如果元组不存在,我希望在相应的列中缺少值。
我遇到了麻烦,因为每个单元格中每个行的每个列表的长度(元组数)对于每一行都是不同的,所以我想在出现时动态分配新的列值。另外,每个单元格都包含一个元组对列表,而不是一个元组。
我尝试了类似this问题的方法,但这仅允许将一个元组扩展为多个列(当您事先知道这些列时)。
然后我查看了this和this,但同样,列数是未知的,所以我得出以下结论:
pd.DataFrame.from_records([{k: v for v, k in row} for row in df.tod])
Out[171]:
2 3 5 6 10 11 15
0 p h NaN b a NaN NaN
1 l NaN NaN NaN NaN x NaN
2 NaN NaN l NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN n
然后,我查看了包含元组here和here的拆分单元格,该单元格查看了将元组转换为序列的方法,但是再一次,这没有用,因为这些示例仅处理的单个元组。已知长度,而不是元组列表
我该如何解决这个问题?
注意:我意识到我没有为“您尝试了什么”编写了很多代码-我的控制台是一堆垃圾,产生了连续的错误。为了保持这种清洁,我将其省略。
答案 0 :(得分:1)
您可以展平元组,然后按生成器创建列名,最后join
到原始DataFrame:
#https://stackoverflow.com/a/45122198/2901002
def mygen(lst):
for item in lst:
yield 'l{}'.format(item)
yield 'n{}'.format(item)
df1 = pd.DataFrame([[b for a in row for b in a] for row in df.tod])
df1.columns = list(mygen(range(1, len(df1.columns) // 2 + 1)))
print(df1)
l1 n1 l2 n2 l3 n3 l4 n4
0 a 10 b 6.0 h 3.0 p 2.0
1 x 11 e 2.0 l 2.0 None NaN
2 r 5 l 5.0 None NaN None NaN
3 n 15 None NaN None NaN None NaN
df = df.join(df1)
print (df)
tod l1 n1 l2 n2 l3 n3 l4 n4
0 [(a, 10), (b, 6), (h, 3), (p, 2)] a 10 b 6.0 h 3.0 p 2.0
1 [(x, 11), (e, 2), (l, 2)] x 11 e 2.0 l 2.0 None NaN
2 [(r, 5), (l, 5)] r 5 l 5.0 None NaN None NaN
3 [(n, 15)] n 15 None NaN None NaN None NaN
答案 1 :(得分:0)
n = max([len(row) for row in df.tod])
f = lambda l: sum(l, ()) + ('-', np.nan)*(n-len(l))
l = [list(f(row)) for row in df.tod]
ndf = pd.DataFrame(l,columns='l1 n1 l2 n2 l3 n3 l4 n4'.split())
# l1 n1 l2 n2 l3 n3 l4 n4
#0 a 10 b 6.0 h 3.0 p 2.0
#1 x 11 e 2.0 l 2.0 - NaN
#2 r 5 l 5.0 - NaN - NaN
#3 n 15 - NaN - NaN - NaN
df.join(ndf)
#
# tod l1 n1 l2 n2 l3 n3 l4 n4
#0 [(a, 10), (b, 6), (h, 3), (p, 2)] a 10 b 6.0 h 3.0 p 2.0
#1 [(x, 11), (e, 2), (l, 2)] x 11 e 2.0 l 2.0 - NaN
#2 [(r, 5), (l, 5)] r 5 l 5.0 - NaN - NaN
#3 [(n, 15)] n 15 - NaN - NaN - NaN