1

I've got a column within a df labelled a. It contains a list of int values. I want to return if they are consecutive or not.

I can do it passing in a single list but I want to iterate over each row.

df = pd.DataFrame({'a': [[0,2], [9,11,12], [0,1,2], [10,11,13]]})

def cons(L):
    return all(n-i == L[0] for i,n in enumerate(L))

print(cons(df['a'][0])) # works

df['cons'] = df['a'].apply(cons, axis=1) # error

intended:

              a    cons
0        [0, 2]   False
1   [9, 11, 12]   False 
2     [0, 1, 2]    True
3  [10, 11, 13]   False
3
  • You're getting an error, TypeError: cons() got an unexpected keyword argument 'axis', because axis isn't a valid keyword argument for Series.apply(), since there's only one axis. In the future, please make a minimal reproducible example including the error, and ask a specific question about it. Stack Overflow is a Q&A site after all. Check out the tour if you haven't already. for more tips, see How to Ask. Commented May 30, 2024 at 13:41
  • Duplicate: Trouble passing in lambda to apply for pandas DataFrame: "TypeError: <lambda>() got an unexpected keyword argument 'axis' ". [I already voted to close as "not reproducible or caused by a typo" before realizing there might be existing questions about this, sorry.] Commented May 30, 2024 at 13:46
  • "a list of string values" - Strings? What you're showing are ints. Maybe you simplified your code but forgot to update the text? Commented May 30, 2024 at 13:51

3 Answers 3

1

Use list comprehension with test if sorted values are same like generated list by minimal and maximal values of lists:

df['cons'] = [sorted(l) == list(range(min(l), max(l)+1)) for l in df['a']]
#alternative
df['cons'] = df['a'].apply(lambda l: sorted(l) == list(range(min(l), max(l)+1)))

Another idea is use np.diff for test if difference is 1 for all values:

df['cons'] = [np.all(np.diff(sorted(l)) == 1) for l in df['a']]
#alternative
df['cons'] = df['a'].apply(lambda l: np.all(np.diff(sorted(l)) == 1))

If want use your solution:

def cons(L):

    return all(n-i==L[0] for i,n in enumerate(L))

df['cons'] = df['a'].apply(cons)
#alternative
df['cons'] = [all(n-i==L[0] for i,n in enumerate(L)) for L in df['a']]

print (df)
              a   cons
0        [0, 2]  False
1   [9, 11, 12]  False
2     [0, 1, 2]   True
3  [10, 11, 13]  False
Sign up to request clarification or add additional context in comments.

Comments

1

Use itertools.pairwise to compare the successive values:

def cons(L):
    from itertools import pairwise
    return all(a==b-1 for a,b in pairwise(L))

df['cons'] = df['a'].apply(cons)

Output:

              a   cons
0  [10, 11, 12]   True
1  [10, 11, 12]   True
2  [10, 11, 12]   True
3  [10, 11, 13]  False

3 Comments

sorry. The aim of the question doesn't change but I should have made a more accurate example.
@tonydanza123 I see, this was indeed not obvious ;)
@tonydanza123 I updated the answer with a pythonic solution, you shouldn't need to sort (O(n*logn))
0

You can try that code to solve your issue:

cons=df1.apply(lambda ss:pd.Series(ss[0]).diff().iloc[1:].eq(1).all(),1)
df1.assign(cons=cons)


             a   cons
0        [0, 2]  False
1   [9, 11, 12]  False
2     [0, 1, 2]   True
3  [10, 11, 13]  False

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.