Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.ix column assignment #1142

Closed
vincentarelbundock opened this issue Apr 27, 2012 · 9 comments

Comments

@vincentarelbundock
Copy link
Contributor

commented Apr 27, 2012

Hi,

I was wondering if there was a good reason why this works:

dat.ix[:,2] + 2

but not this:

dat.ix[:,2] = dat.ix[:,2] + 2
@changhiskhan

This comment has been minimized.

Copy link
Contributor

commented Apr 27, 2012

What does dat look like? For example, I can do the following:

In [16]: dat = DataFrame(np.random.randn(5, 3))

In [17]: dat.ix[:, 2] + 2
Out[17]:
0 1.681506
1 1.930261
2 1.274177
3 3.159334
4 3.843346
Name: 2

In [18]: dat.ix[:, 2] = dat.ix[:, 2] + 2

In [19]: dat.ix[:, 2]
Out[19]:
0 1.681506
1 1.930261
2 1.274177
3 3.159334
4 3.843346
Name: 2

@vincentarelbundock

This comment has been minimized.

Copy link
Contributor Author

commented Apr 27, 2012

In [10]: dat.ix[:,20] = dat.ix[:,20]
---------------------------------------------------------------------------
IndexingError                             Traceback (most recent call last)
/home/myname/<ipython-input-10-18d0ebbb8418> in <module>()
----> 1 dat.ix[:,20] = dat.ix[:,20]

/usr/lib/python2.7/site-packages/pandas/core/indexing.py in __setitem__(self, key, value)
     63             indexer = self._convert_to_indexer(key)
     64 
---> 65         self._setitem_with_indexer(indexer, value)
     66 
     67     def _convert_tuple(self, key):

/usr/lib/python2.7/site-packages/pandas/core/indexing.py in _setitem_with_indexer(self, indexer, value)
     85 
     86             if not np.isscalar(value):
---> 87                 raise IndexingError('setting on mixed-type frames only '
     88                                     'allowed with scalar values')
     89 

IndexingError: setting on mixed-type frames only allowed with scalar values

In [11]: dat.ix[:,20]
Out[11]: 
Country Code
AFG                530
ALB               9800
DZA              41800
ASM                 12
ADO                NaN
AGO                NaN
ATG                228
ARB             186160
ARG             180000
ARM                NaN
AUS                NaN
AUT             294000
AZE                NaN
BHS                 71
BHR                NaN
...
AFG            NaN
BDI            NaN
CAF            NaN
ZAR            NaN
CIV            NaN
GNB            NaN
HTI            NaN
IRQ            NaN
KSV            NaN
LBR            NaN
NPL            NaN
SLB            NaN
SOM            NaN
SDN            NaN
TMP            NaN
Name: 1976, Length: 215786
@changhiskhan

This comment has been minimized.

Copy link
Contributor

commented Apr 27, 2012

Ah you have heterogeneous data.
dat.ix[:, 20] retrieves a series so + 2 works as expected.
Assignment for heterogeneous DataFrames via .ix is different because internally the data is split between multiple homogeneous blocks.
You can always do dat[col_name] = dat[col_name] + 2.
(
We can maybe think about being even more clever with assignment with .ix when it's just a single column (or maybe check that they're in the same block?).

@vincentarelbundock

This comment has been minimized.

Copy link
Contributor Author

commented Apr 27, 2012

Ah, I see. Thanks for looking into this. Coming from R, it just feels much more natural to use the .ix indexing, since I never remember which axis it'll slice on if I only pass one list of labels. I also usually refer to columns by position, not labels, since it's convenient to loop over a range() call. I guess I can specify columns by indexing dat.columns[i], but that feels like a workaround for something that should be straightforward.

Unfortunately, I just started playing around with python/pandas a few days ago, so I'm not in a position to contribute code, but thanks for considering!

@lodagro

This comment has been minimized.

Copy link
Contributor

commented Apr 27, 2012

fyi, you can loop over dat.columns directly, this will give you the column labels.

for label in dat.columns:
    print label
    print dat[label]

Other option is to use df.iteritems()
You can also use dat.icols() and dat.irow() methods, if you want positional indexing.

good luck with pandas

@vincentarelbundock

This comment has been minimized.

Copy link
Contributor Author

commented Apr 27, 2012

Of course I can! Thanks for the tip lodagro!

@wesm

This comment has been minimized.

Copy link
Member

commented Apr 27, 2012

I'll look into this, should be fairly easy to fix

@ghost ghost assigned wesm May 3, 2012

@wesm wesm closed this in 6bf6274 May 7, 2012

@wesm

This comment has been minimized.

Copy link
Member

commented May 7, 2012

This is all set

@vincentarelbundock

This comment has been minimized.

Copy link
Contributor Author

commented May 7, 2012

Thanks for your work!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.