熊猫用同一列中的下一个可用值填充列值

时间:2018-08-19 15:29:22

标签: 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 | 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值填充序列
fill-in-a-missing-values-in-range-with-pandas
missing-data-insert-rows-in-pandas-and-fill-with-nan

预先感谢您的回答。 问候

2 个答案:

答案 0 :(得分:3)

设置

print(df)

   Inventory_No   Description   Group       PLU
0      93120007          Coke  Drinks      1000
1      93120008     Diet Coke  Drinks      1003
2      93120009     Coke Zero  Drinks      1104
3      93120010         Fanta  Drinks      1105
4      93120011   White Bread   Bread  93120011
5      93120012    whole Meal   Bread  93120012
6      93120013  Whole Grains   Bread    110011
7      93120014    Flat white  Breads   1115092

首先,让我们创建一个值列表,我们可以使用这些值来填充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

答案 1 :(得分:1)

示例DataFrame:

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建立一个可迭代的对象(因此范围最多为9999-例如:仅4位数字):

spare_code = iter(range(start_at, 10000))

如果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