Python 使用同一列中的下一个可用值填充列值

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

我正在处理一个数据集,其中PLU列中的值分散在各个地方,如: 我在500多列中有4列:

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)Do
df.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)Do
df.PLU.dtype
检查并显示输出时,我猜
PLU
是一个字符串列,它给了我dtype('O'))当我完成df.PLU.dtype时