Python 使用同一列中的下一个可用值填充列值
我正在处理一个数据集,其中PLU列中的值分散在各个地方,如: 我在500多列中有4列:Python 使用同一列中的下一个可用值填充列值,python,python-3.x,pandas,Python,Python 3.x,Pandas,我正在处理一个数据集,其中PLU列中的值分散在各个地方,如: 我在500多列中有4列: Inventory_No | Description | Group | PLU ---------------------------------------------- 93120007 | Coke |Drinks | 1000 93120008 | Diet Coke |Drinks | 1003 93120009 | Coke Zero |Drinks
Inventory_No | Description | Group | PLU
----------------------------------------------
93120007 | Coke |Drinks | 1000
93120008 | Diet Coke |Drinks | 1003
93120009 | Coke Zero |Drinks | 1104
93120010 | Fanta |Drinks | 1105
93120011 | White Bread |Bread | 93120011
93120012 | whole Meal |Bread | 93120012
93120013 | Whole Grains|Bread | 110011
93120014 | Flat white |Breads | 1115092
我希望我的输出如下所示,如果PLU列中有任何长度超过6位的值,系统将检查长度小于4位的PLU序列中的下一个可用数字,并在其中添加增量1,然后将PLU值分配给该行,并且不会更改任何现有长度小于6位的PLU:
Inventory_No | Description | Group | PLU
----------------------------------------------
93120007 | Coke |Drinks | 1000
93120011 | White Bread |Bread | 1001
93120012 | whole Meal |Bread | 1002
93120008 | Diet Coke |Drinks | 1003
93120014 | Flat white |Breads | 1004
. | . | . | .
. | . | . | .
. | . | . | .
93120009 | Coke Zero |Drinks | 1104
93120010 | Fanta |Drinks | 1105
93120013 | Whole Grains|Bread | 110011
我希望序列中的下一个可用值小于6位,并将其递增1,如果它找到任何数量的递增值的序列,则跳过该序列,并从序列后的下一个可用值开始,只要序列长度小于6位:我已经检查了以下链接,它们是为了用0或Nan值填充序列
提前感谢您的回答。 关于设置 首先,让我们创建一个值列表,用于填充
df.PLU
中未包含的值:
fillers = [
i for i in np.arange(df.PLU.min(), df.PLU.min() + len(df)) if i not in set(df.PLU)
]
# [1001, 1002, 1004, 1005, 1006, 1007]
现在,我们可以使用新值制作一个系列并填充:
condition = df.PLU.ge(1e6)
s = df.loc[condition]
fill = pd.Series(fillers[len(s):], index=s.index)
df.assign(PLU=df.PLU.mask(condition).fillna(fill).astype(int)).sort_values('PLU')
输出:
Inventory_No Description Group PLU
0 93120007 Coke Drinks 1000
4 93120011 White Bread Bread 1001
5 93120012 whole Meal Bread 1002
1 93120008 Diet Coke Drinks 1003
7 93120014 Flat white Breads 1004
2 93120009 Coke Zero Drinks 1104
3 93120010 Fanta Drinks 1105
6 93120013 Whole Grains Bread 110011
设置
首先,让我们创建一个值列表,用于填充df.PLU
中未包含的值:
fillers = [
i for i in np.arange(df.PLU.min(), df.PLU.min() + len(df)) if i not in set(df.PLU)
]
# [1001, 1002, 1004, 1005, 1006, 1007]
现在,我们可以使用新值制作一个系列并填充:
condition = df.PLU.ge(1e6)
s = df.loc[condition]
fill = pd.Series(fillers[len(s):], index=s.index)
df.assign(PLU=df.PLU.mask(condition).fillna(fill).astype(int)).sort_values('PLU')
输出:
Inventory_No Description Group PLU
0 93120007 Coke Drinks 1000
4 93120011 White Bread Bread 1001
5 93120012 whole Meal Bread 1002
1 93120008 Diet Coke Drinks 1003
7 93120014 Flat white Breads 1004
2 93120009 Coke Zero Drinks 1104
3 93120010 Fanta Drinks 1105
6 93120013 Whole Grains Bread 110011
数据帧示例:
df = pd.DataFrame({'PLU': ['1001', '1002', '1110679', '1003', '1005', '12345', '1234567', '1231231231312', '1003', '1110679']}
获取下一个未使用的4位数字:
start_at = int(df['PLU'][df.PLU.str.len() == 4].max()) + 1
构建一个从起始数字到10000的iterable(因此范围最多为9999-例如:仅4位数字):
如果PLU的长度超过6个字符,则替换为下一个备用代码
to_replace = df['PLU'].str.len() > 6
df.loc[to_replace, 'PLU'] = df.PLU[to_replace].map(lambda v: str(next(spare_code)))
为您提供一个修改后的df
:
PLU
0 1001
1 1002
2 1006
3 1003
4 1005
5 12345
6 1007
7 1008
8 1003
9 1009
数据帧示例:
df = pd.DataFrame({'PLU': ['1001', '1002', '1110679', '1003', '1005', '12345', '1234567', '1231231231312', '1003', '1110679']}
获取下一个未使用的4位数字:
start_at = int(df['PLU'][df.PLU.str.len() == 4].max()) + 1
构建一个从起始数字到10000的iterable(因此范围最多为9999-例如:仅4位数字):
如果PLU的长度超过6个字符,则替换为下一个备用代码
to_replace = df['PLU'].str.len() > 6
df.loc[to_replace, 'PLU'] = df.PLU[to_replace].map(lambda v: str(next(spare_code)))
为您提供一个修改后的df
:
PLU
0 1001
1 1002
2 1006
3 1003
4 1005
5 12345
6 1007
7 1008
8 1003
9 1009
遍历
PLU
中的所有值并从前面的行中指定递增的值还不够吗?我猜你隐含地假设你分配的数字不会增长超过6位数,当它们可能与从外部分配的数字冲突时?因为你无论如何都会改变一些加号。。。你能不能不重新写一遍?如果需要一致地引用其他内容,这很好,但在您更改它们的情况下就不会这样了。。。所以似乎如果您愿意这样做,您应该从1000开始给他们所有全新的代码。遍历PLU
中的所有值并从前面的行中指定一个递增的值还不够吗?我猜你隐含地假设你分配的数字不会增长超过6位数,当它们可能与从外部分配的数字冲突时?因为你无论如何都会改变一些加号。。。你能不能不重新写一遍?如果需要一致地引用其他内容,这很好,但在您更改它们的情况下就不会这样了。。。所以似乎如果你乐意这么做,你应该给他们所有从1000开始的全新代码#user3483203我已经尝试了你的代码填充器=[I for I in np.arange(df.PLU.min(),df.PLU.min()+len(df)),如果我不在set(df.PLU)],我得到以下错误:TypeError:必须是str,而不是df.PLU.min()+len(df)上的int)你的PLU列的数据类型是什么?当我使用type(df.PLU)Dodf.PLU.dtype
检查并显示输出时,这是一个系列,我猜PLU
是一个字符串列。当我完成df.PLU.dtype时,它给了我dtype('O')user3483203我已经尝试了你的代码填充符=[I for I in np.arange(df.PLU.min(),df.PLU.min())+len(df))如果我不在集合(df.PLU)]中,并且得到以下错误:TypeError:必须是str,而不是df.PLU.min()上的int+len(df))你的PLU列的数据类型是什么?当我使用type(df.PLU)Dodf.PLU.dtype
检查并显示输出时,我猜PLU
是一个字符串列,它给了我dtype('O'))当我完成df.PLU.dtype时