给定一个数据框df,(实际情况是+1000行df)。 ColB的元素是列表列表。
ColA ColB
0 'A' [['a','b','c'],['d','e','f']]
1 'B' [['f','g','h'],['i','j','k']]
2 'A' [['l','m','n'],['o','p','q']]
如何使用不同列中的元素有效地创建ColC这是一个字符串,如下所示:
ColC
'A>+a b:c,+d e:f'
'B>+f g:h,+i j:k'
'A>+l m:n,+o p:q'
受此启发,我尝试了以下方法使用df.apply:
df['ColC'] = df.apply(lambda x:'%s>' % (x['ColA']),axis=1)
这适用于字符串的前2个元素。 其余的人很难过。
像这样吗
df['ColC'] = df.ColA + '>+' + df.ColB.str[0].str[0] + \
' ' + df.ColB.str[0].str[1] + ':' + \
df.ColB.str[0].str[2] + ',+' + \
df.ColB.str[1].str[0] + ' ' + \
df.ColB.str[1].str[1] + ':' + \
df.ColB.str[1].str[2]
输出:
ColA ColB ColC
0 A [[a, b, c], [d, e, f]] A>+a b:c,+d e:f
1 B [[f, g, h], [i, j, k]] B>+f g:h,+i j:k
2 A [[l, m, n], [o, p, q]] A>+l m:n,+o p:q
时机
df = pd.concat([df] * 333)
温氏方法
%%timeit df[['t1','t2']]=df['ColB'].apply(pd.Series).applymap(lambda x
: ('{} {}:{}'.format(x[0],x[1],x[2]))) df.ColA+'>+'+df.t1+',+'+df.t2
1个循环,最佳3:每个循环363毫秒
米拉杜洛法
%%timeit df.apply(lambda r:'{}>+{} {}:{},+{}
{}:{}'.format(*flatten(r)), axis=1)
10个循环,最佳3:每个循环74.9毫秒
斯科特波士顿方法
%%timeit df.ColA + '>+' + df.ColB.str[0].str[0] + \
' ' + df.ColB.str[0].str[1] + ':' + \
df.ColB.str[0].str[2] + ',+' + \
df.ColB.str[1].str[0] + ' ' + \
df.ColB.str[1].str[1] + ':' + \
df.ColB.str[1].str[2]
100次循环,最佳3:每个循环12.4毫秒
改变图片。 我什至不知道那是你.....
@WEN LOL ...好的,今晚过后。 今天必须支持Astros!
@miradulo哦...我将原始数据的大小乘以333,以模拟1000行。
@ScottBoston嗯,很公平-当行足够大时,我猜认为暴力字符串表示方法将对性能起主导作用,+ 1
@miradulo与axis = 1一起应用很慢.... :)
@ScottBoston是的,但据我所知,这是归纳总结的唯一方法……叹了口气。
还有一个答案:
df['ColC'] = df.apply(lambda x: '%s>+%s %s:%s,+%s%s:%s'% tuple([x['ColA']]+x['ColB'][0]+x['ColB'][1]),axis=1)
如果我们如下使用flatten函数
def flatten(l):
for el in l:
if isinstance(el, collections.Iterable) and not isinstance(el, (str, bytes)):
yield from flatten(el)
else:
yield el
如该答案所示,那么我们可以轻松地apply使用扁平化元素格式化字符串。
>>> df.apply(lambda r:'{}>+{} {}:{},+{} {}:{}'.format(*flatten(r.values)), axis=1)
0 A>+a b:c,+d e:f
1 B>+f g:h,+i j:k
2 A>+l m:n,+o p:q
dtype: object
希望这会很好地推广。
>>> row_formatter = lambda r: '{}>+{} {}:{},+{} {}:{}'.format(*flatten(r.values))
>>> df.apply(row_formatter, 1)
0 A>+a b:c,+d e:f
1 B>+f g:h,+i j:k
2 A>+l m:n,+o p:q
dtype: object
您正确使用apply
df[['t1','t2']]=df['colB'].apply(pd.Series).applymap(lambda x : ('{} {}:{}'.format(x[0],x[1],x[2])))
df.colA+'>+'+df.t1+',+'+df.t2
Out[648]:
0 A>+a b:c,+d e:f
1 B>+f g:h,+i j:k
2 C>+l m:n,+o p:q
你能解释一下:df [[t1,t2]]。 谢谢
@hernanavella我创建了两个新列来恢复临时值:-),然后我们可以使用简单的添加来创建所需的字符串
这是我的2美分,也使用apply
定义可以应用于数据框并使用字符串格式分析列的函数
def get_string(x):
col_a = x.ColA
col_b = (ch for ch in x.ColB if ch.isalnum())
string = '{0}>+{1} {2}:{3},+{4} {5}:{6}'.format(col_a.strip("\'"), *col_b)
return(string)
df['ColC'] = df.apply(get_string, axis=1)
df.ColC
0 A>+a b:c,+d e:f
1 B>+f g:h,+i j:k
2 A>+l m:n,+o p:q
我喜欢这样做是因为修改格式很容易,尽管以这种方式使用Apply可能很慢