我有一个这样的数据帧df
,
A length
0 648702831 9
1 26533315 8
2 366 3
3 354701058 9
4 25708239 8
5 70554 5
6 1574512 7
7 3975 4
现在,我想根据这样的条件创建一列,
if ['length] == 9 or ['length] == 5:
then ['new_col'] = First 5 Characters of ['A']
else if ['length] == 8 or ['length] == 4:
then ['new_col'] = "0" & First 4 Characters of ['A']
else if ['length] == 7 or ['length] == 3:
then ['new_col'] = "00" & First 3 Characters of ['A']
else
['new_col'] = ['A']
对于上述情况,我创建了以下逻辑来检查(对于具有10,000行的文件,这需要很多时间)
for i in df['length']:
if i == 9 or i == 5:
df['new_col'] = df['A'].astype(str).str[:5]
elif i == 8 or i == 4:
df['new_col'] = "0" + df['A'].astype(str).str[:4]
elif i == 7 or i == 3:
df['new_col'] = "00" + df['A'].astype(str).str[:3]
else:
df['new_col'] = df['A']
我得到以下输出,
A length new_col
0 648702831 9 06487
1 26533315 8 02653
2 366 3 0366
3 354701058 9 03547
4 5708239 8 05708
5 70554 5 07055
6 1574512 7 01574
7 3975 4 03975
这不是我想要的,它似乎仅适用于长度为8或4时在前面加上“ 0”的第二种条件。
我需要这样的输出
A length new_col
0 648702831 9 64870
1 26533315 8 02653
2 366 3 00366
3 354701058 9 35470
4 5708239 8 05708
5 70554 5 70554
6 1574512 7 00157
7 3975 4 03975
如何实现这一目标,并且如果有一种pandas
方式可以花费更少的时间,那将是很好的。任何建议,将不胜感激。
答案 0 :(得分:3)
使用zfill
进行字符串切片。为了提高速度,请使用列表理解。
m = {1: 5, 0: 4, 3: 3}
df['new_col'] = [
x[:m.get(y % 4, 4)].zfill(5) for x, y in zip(df['A'].astype(str), df['length'])]
df
A length new_col
0 648702831 9 64870
1 26533315 8 02653
2 366 3 00366
3 354701058 9 35470
4 25708239 8 02570
5 70554 5 70554
6 1574512 7 00157
7 3975 4 03975
要处理默认情况,我们可以在调用zfill
时进行一些额外的检查:
df = df.append({'A' : 50, 'length': 2}, ignore_index=True)
m = {1: 5, 0: 4, 3: 3}
df['new_col'] = [
x[:m.get(y % 4, 4)].zfill(5 if y % 4 in m else 0)
for x, y in zip(df['A'].astype(str), df['length'])
]
df
A length new_col
0 648702831 9 64870
1 26533315 8 02653
2 366 3 00366
3 354701058 9 35470
4 25708239 8 02570
5 70554 5 70554
6 1574512 7 00157
7 3975 4 03975
8 50 2 50 # Default case.
答案 1 :(得分:3)
您可以将列表理解与字典配合使用。考虑到熊猫str
方法没有向量化,这完全可以接受。
d = {5: 5, 9: 5, 8: 4, 4: 4, 3: 3, 7: 3}
zipper = zip(df['A'].astype(str), df['length'])
df['new_col'] = [A[:d[L]].zfill(5) if L in d else A for A, L in zipper]
print(df)
A length new_col
0 648702831 9 64870
1 26533315 8 02653
2 366 3 00366
3 354701058 9 35470
4 25708239 8 02570
5 70554 5 70554
6 1574512 7 00157
7 3975 4 03975
8 12 2 12
答案 2 :(得分:3)
修正您的代码
df['new_col']=''
for i,j in zip(df['length'],df.index):
df.A = df.A.astype(str)
if i == 9 or i == 5:
df.loc[j,'new_col'] = df.loc[j,'A'][:5]
elif i == 8 or i == 4:
df.loc[j, 'new_col'] = "0" + df.loc[j,'A'][:4]
elif i == 7 or i == 3:
df.loc[j, 'new_col'] = "00" + df.loc[j,'A'][:3]
else:
df.loc[j, 'new_col']= df.loc[j,'A']
df
Out[52]:
A length new_col
0 648702831 9 64870
1 26533315 8 02653
2 366 3 00366
3 354701058 9 35470
4 25708239 8 02570
5 70554 5 70554
6 1574512 7 00157
7 3975 4 03975
答案 3 :(得分:0)
您可以使用lambda函数来做到这一点:
df = pd.DataFrame({'A':[298347,9287384, 983, 9283, 894, 1]})
df['new_col'] = df['A'].apply(lambda x: '{0:0>8}'.format(x))
A Col1
0 298347 00298347
1 9287384 09287384
2 983 00000983
3 9283 00009283
4 894 00000894
5 1 00000001