0

The following function:

def func(x):
    for k in x['slices']:
        for j in k:
            print(x['low'].iloc[j]) 

applied in the following manner works:

func(test)

but as follow doesn't:

test.apply(func, axis=1)

Would you be able to determine why?


EDIT: I used the print only for debug purpose: the function used to be :

def func(x):
    result=[]
    for k in x:
        for j in k:    
            result.append(x['low'].iloc[j])
    return result

which also didn't work

Below the elements to reconstructs the data.

df = pd.DataFrame(dict, columns=["low", "slices"])

   dict = {'low': {0: 1207.25,
      1: 1207.5,
      2: 1205.75,
      3: 1206.0,
      4: 1201.0,
      5: 1202.75,
      6: 1203.75},
     'slices': {0: [slice(1, 2, None)],
      1: [slice(1, 3, None), slice(2, 3, None)],
      2: [slice(1, 4, None), slice(2, 4, None), slice(3, 4, None)],
      3: [slice(1, 5, None),
       slice(2, 5, None),
       slice(3, 5, None),
       slice(4, 5, None)],
      4: [slice(1, 6, None),
       slice(2, 6, None),
       slice(3, 6, None),
       slice(4, 6, None),
       slice(5, 6, None)],
      5: [slice(1, 7, None),
       slice(2, 7, None),
       slice(3, 7, None),
       slice(4, 7, None),
       slice(5, 7, None),
       slice(6, 7, None)],
      6: [slice(1, 8, None),
       slice(2, 8, None),
       slice(3, 8, None),
       slice(4, 8, None),
       slice(5, 8, None),
       slice(6, 8, None),
       slice(7, 8, None)]}}
6
  • What is the observed behavior when you use apply? Does it throw an error? Does it print empty strings? More information will help to answer the question. Commented Jan 3, 2017 at 23:26
  • @dave When using the apply() the error returned is: an integer is required and KeyError: ('slices', 'occurred at index slices'). Note that when using func(test), it returns the correct output with no error message. Commented Jan 3, 2017 at 23:31
  • @jimbasquiat What do you expect the outcome to look like, a new Series containing lists from the slices? Commented Jan 3, 2017 at 23:33
  • @MosesKoledoye yes the output looks something like that: 1 1207.5 Name: low, dtype: float64 1 1207.50 2 1205.75 Name: low, dtype: float64 2 1205.75 Name: low, dtype: float64 1 1207.50 2 1205.75 3 1206.00 Name: low, dtype: float64 2 1205.75 3 1206.00 Name: low, dtype: float64 3 1206.0 Name: low, dtype: float64 1 1207.50 2 1205.75 3 1206.00 4 1201.00 I didnt post it at first as it is quite long. Yes it is Series based on the slices Commented Jan 3, 2017 at 23:38
  • 1
    .apply does not work like so. print returns None and the output you have is not valid Series object Commented Jan 3, 2017 at 23:40

1 Answer 1

2

define your function this way

def fun(slices):
    return [df.low.loc[s].tolist() for s in slices]

And apply over the slices column

df['slices_low'] = df.slices.apply(fun)

df

enter image description here

Sign up to request clarification or add additional context in comments.

6 Comments

no i cannot change so drastically the function. I want to understand why func(test) and test.apply(func) are different. I dont understand why you say that test.apply(func, axis=0) is equivalent to calling func(test['low']) then calling func(test['slices']) separately. For me that would be true of map but not of apply. apply considers each row as a Series, no?
no! apply treats each column as a series unless you pass axis=1. The axis parameter tells apply which axis to use as the index of the series. If axis=0 the row indices will be used as the index and that means columns are the objects that are being passed to the apply function.
yes i think axis=1 is the first thing i tried actually. But it should work though right? it returns TypeError: ("'slice' object is not iterable", 'occurred at index 0') Sorry i'm confused i tried so many things...
No again. Your function anticipates a dataframe hence the double loop. You iterate through each element in the slices column, then through each slice. Understand that when you use apply, pd.Series objects are passed to the function. That means that x['slices'] is already the list of slices you are looking for. You don't want to iterate again.
Also, when you slice within the function, you are slicing the object that is passed to the function and not the dataframe in the outer scope. That means will get another error or not get the full slices you are looking for. My sincerest advice is to look for another way or rewrite that function. Sometimes questions like "This should work, why doesn't it work?" Should be "I'm trying to accomplish this, how do I do it?"
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.