May not be the best way of arrange data in real case, but it serves a good example:
In [16]:
import operator
In [17]:
DF=pd.DataFrame({'Val1':[[2013, 37722.322],[1998, 32323.232]],
'Val2':[[2013, 37722.322],[1998, 32323.232]]})
In [18]:
print DF
Val1 Val2
0 [2013, 37722.322] [2013, 37722.322]
1 [1998, 32323.232] [1998, 32323.232]
[2 rows x 2 columns]
apply gives wrong result
In [19]:
print DF.apply(operator.itemgetter(-1), axis=1)
Val1 Val2
0 2013 37722.322
1 1998 32323.232
[2 rows x 2 columns]
but applymap gives the right result!
In [20]:
print DF.applymap(operator.itemgetter(-1))
Val1 Val2
0 37722.322 37722.322
1 32323.232 32323.232
[2 rows x 2 columns]
Why could it happen?
It is easier to see what is happening if you use
df = pd.DataFrame({'Val1':[[1, 2],[3, 4]],
'Val2':[[5, 6],[7, 8]]})
Val1 Val2
0 [1, 2] [5, 6]
1 [3, 4] [7, 8]
df.apply(operator.itemgetter(-1), axis=1) calls operator.itemgetter(-1) on each row.
For example, on the first row, operator.itemgetter(-1) returns the last item, which is [5, 6].
Since this value is iterable, its values are then assigned to the two columns Val1 and Val2. So the result is
In [149]: df.apply(operator.itemgetter(-1), axis=1)
Out[149]:
Val1 Val2
0 5 6
1 7 8
In contrast, applymap operates on each cell in the DataFrame individually, so operator.itemgetter(-1) returns the last item from each cell.
In [150]: df.applymap(operator.itemgetter(-1))
Out[150]:
Val1 Val2
0 2 6
1 4 8
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With