我有一个pandas数据框架,其中一列包含每一行增加1的项目编号。
df1 = pd.DataFrame({
"item_number" : [1, 2, 3, 4, 5, 6, 8, 10],
"col_A" : ['aaa','bbb','ccc','ddd','eee','fff','hhh', 'jjj']})
df1
item_number col_A
0 1 aaa
1 2 bbb
2 3 ccc
3 4 ddd
4 5 eee
5 6 fff
6 8 hhh
7 10 jjj
可以看到,项目编号在6到8和8到10之间增加了2。是否有一种方法来编写一个函数,将跳过的数字列表,即。['7','9']否则,返回True
s=pd.Series(range(df['item_number'].min(), (df['item_number'].max()+1)))
s[~s.isin(df['item_number'])].values
array([7, 9], dtype=int64)
一行:
set(range(df1.item_number.min(), df1.item_number.max()+1)) - set(df1.item_number) or True
您可以利用Python的集合和列表操作来确定您所提议的条件是否满足输入列表:
li = [1, 2, 3, 4, 5, 6, 8, 10]
def fun(l):
a = list(set(list(range(l[0], l[-1]+1))) - set(l))
if a == []:
return True
else:
return a
print(fun(li))
输出:
[9, 7]
如果您希望列表元素按顺序返回,也可以使用return sorted(a)
。
使用range
和np.setdiff1d
:
In [1518]: import numpy as np
In [1519]: rng = range(df1.item_number.min(), df1.item_number.max() + 1)
In [1523]: res = np.setdiff1d(rng, df1.item_number)
In [1524]: res
Out[1524]: array([7, 9])
可以这样做:
def foo(df):
x = df.set_index('item_number').reindex(range(df.item_number.min(), df.item_number.max() + 1))
x = list(x.index[x.col_A.isna()])
return x if x else True
例子:
y = foo(df1)
print(y)
y = foo(df1.loc[range(1, 6)])
print(y)
输出:
[7, 9]
True