I have been asked to revive a Spearman Correlation code that requires a module that was authored by someone else and hasn't been updated since 2018 (module name is fouriertransform: https://github.com/FluvialSeds/fouriertransform) to work on Python 3.11.7. Since publication, the .ix indexing function from the pandas module has been deprecated. I keep receiving "AttributeError: 'DataFrame' object has no attribute 'ix'". This error populates when I change the .ix to .loc and to .iloc, as suggested for other users encountering the same problem with using .ix. I don't know what else to try, as I'm very new to Python (and do very little code writing). I'm unsure if this matters, but I am editing this code in Sublime Text and running it in IPython (both were recommended by my supervisor), but the files are registering as modified in the Windows File Explorer and the changes do show up on the errors.
My code has me import a bunch of files, then extracts the relevant data from those files and does some statistical analyses on the extracted data using the fouriertransform module. The error comes from generating a summary of the extracted data.
Original fouriertransform module crosstable_helper.py code:
#define function to calculate modified aromaticity index
def _calc_pct(ct, cols, weights):
'''
Calculates percentages for generating a summary table.
Parameters
----------
ct : ft.CrossTable
``CrossTable`` instance containing the formulae of interest.
cols : list
List of column names to be calculated (required input for indexing
purposes. Columns get mis-aligned if omitted).
weights : str
String of weights to use for %RA calculates, either compound
categories or classes. Inputed from the _gen_sum_tab function.
Returns
-------
pcts : pd.DataFrame
Resulting dataframe of calculated percentages for each sample.
Raises
------
AssertionError
If percentages do not add up to 100.
'''
#call intensites df for shorthand
df = ct.intensities
#calculate totals
tot_N = np.sum(df > 0)
tot_int = np.sum(df)
#extract class / category names
names = weights.unique()
#make empty dataframe of results
pcts = pd.DataFrame(index = ct.sam_names, columns = cols)
#loop through each class / category and store results
for n in names:
#extract compounds within class/category
ind = np.where(weights == n)[0]
cforms = df.ix[ind]
#calculate class/category formula numbers and intensities
c_N = np.sum(cforms > 0)
c_int = np.sum(cforms)
#calculate percentages
c_pct_N = 100*c_N/tot_N
c_pct_RA = 100*c_int/tot_int
#store results
pcts[n + '_%N'] = c_pct_N
pcts[n + '_%RA'] = c_pct_RA
#assert that it all adds up to 200 (sum of N-based and RA-based)
assert (pcts.sum(axis = 1) - 200 < 1e-6).all(), \
'Calculated percentages do not add up within 1 part per million!' \
' Something is not assigned a compound class / category!'
return pcts
Original Error (currently I am ignoring the FutureWarnings):
In [18]: sum_tab = ct.generate_summary()
C:\Users\peter\anaconda3\Lib\site-packages\numpy\core\fromnumeric.py:86: FutureWarning: The behavior of DataFrame.sum with axis=None is deprecated, in a future version this will reduce over both axes and return a scalar. To retain the old behavior, pass axis=0 (or do not pass axis)
return reduction(axis=axis, out=out, **passkwargs)
C:\Users\peter\anaconda3\Lib\site-packages\numpy\core\fromnumeric.py:86: FutureWarning: The behavior of DataFrame.sum with axis=None is deprecated, in a future version this will reduce over both axes and return a scalar. To retain the old behavior, pass axis=0 (or do not pass axis)
return reduction(axis=axis, out=out, **passkwargs)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-18-6dabb3fee1af> in ?()
----> 1 sum_tab = ct.generate_summary()
~\anaconda3\Lib\site-packages\fouriertransform\crosstable.py in ?(self)
462 ----------
463 Santi-Temkiv et al. (2013), PLoS One, doi:10.1371/journal.pone.0053550.
464 '''
465
--> 466 sum_df = _gen_sum_tab(self)
467
468 return sum_df
~\anaconda3\Lib\site-packages\fouriertransform\crosstable_helper.py in ?(ct)
1022
1023 sum_df['AImod_RA'] = \
1024 np.sum(ct.intensities.multiply(ct.AImod, axis = 0))/tot_int
1025
-> 1026 sum_df[cls_mets] = _calc_pct(ct, cls_mets, ct.cmpd_class)
1027 sum_df[cat_mets] = _calc_pct(ct, cat_mets, ct.cmpd_cat)
1028
1029 return sum_df
~\anaconda3\Lib\site-packages\fouriertransform\crosstable_helper.py in ?(ct, cols, weights)
524 for n in names:
525
526 #extract compounds within class/category
527 ind = np.where(weights == n)[0]
--> 528 cforms = df.ix[ind]
529
530 #calculate class/category formula numbers and intensities
531 c_N = np.sum(cforms > 0)
~\anaconda3\Lib\site-packages\pandas\core\generic.py in ?(self, name)
6200 and name not in self._accessors
6201 and self._info_axis._can_hold_identifiers_and_holds_name(name)
6202 ):
6203 return self[name]
-> 6204 return object.__getattribute__(self, name)
AttributeError: 'DataFrame' object has no attribute 'ix'
Fix attempt #1, changed .ix in the crosstable_helper.py file to .loc:
In [19]: sum_tab = ct.generate_summary()
C:\Users\peter\anaconda3\Lib\site-packages\numpy\core\fromnumeric.py:86: FutureWarning: The behavior of DataFrame.sum with axis=None is deprecated, in a future version this will reduce over both axes and return a scalar. To retain the old behavior, pass axis=0 (or do not pass axis)
return reduction(axis=axis, out=out, **passkwargs)
C:\Users\peter\anaconda3\Lib\site-packages\numpy\core\fromnumeric.py:86: FutureWarning: The behavior of DataFrame.sum with axis=None is deprecated, in a future version this will reduce over both axes and return a scalar. To retain the old behavior, pass axis=0 (or do not pass axis)
return reduction(axis=axis, out=out, **passkwargs)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-19-6dabb3fee1af> in ?()
----> 1 sum_tab = ct.generate_summary()
~\anaconda3\Lib\site-packages\fouriertransform\crosstable.py in ?(self)
462 ----------
463 Santi-Temkiv et al. (2013), PLoS One, doi:10.1371/journal.pone.0053550.
464 '''
465
--> 466 sum_df = _gen_sum_tab(self)
467
468 return sum_df
~\anaconda3\Lib\site-packages\fouriertransform\crosstable_helper.py in ?(ct)
1022
1023 sum_df['AImod_RA'] = \
1024 np.sum(ct.intensities.multiply(ct.AImod, axis = 0))/tot_int
1025
-> 1026 sum_df[cls_mets] = _calc_pct(ct, cls_mets, ct.cmpd_class)
1027 sum_df[cat_mets] = _calc_pct(ct, cat_mets, ct.cmpd_cat)
1028
1029 return sum_df
~\anaconda3\Lib\site-packages\fouriertransform\crosstable_helper.py in ?(ct, cols, weights)
524 for n in names:
525
526 #extract compounds within class/category
527 ind = np.where(weights == n)[0]
--> 528 cforms = df.loc[ind]
529
530 #calculate class/category formula numbers and intensities
531 c_N = np.sum(cforms > 0)
~\anaconda3\Lib\site-packages\pandas\core\generic.py in ?(self, name)
6200 and name not in self._accessors
6201 and self._info_axis._can_hold_identifiers_and_holds_name(name)
6202 ):
6203 return self[name]
-> 6204 return object.__getattribute__(self, name)
AttributeError: 'DataFrame' object has no attribute 'ix'
Fix attempt #2, changed .loc to .iloc in crosstable_helper.py file
In [21]: sum_tab = ct.generate_summary()
C:\Users\peter\anaconda3\Lib\site-packages\numpy\core\fromnumeric.py:86: FutureWarning: The behavior of DataFrame.sum with axis=None is deprecated, in a future version this will reduce over both axes and return a scalar. To retain the old behavior, pass axis=0 (or do not pass axis)
return reduction(axis=axis, out=out, **passkwargs)
C:\Users\peter\anaconda3\Lib\site-packages\numpy\core\fromnumeric.py:86: FutureWarning: The behavior of DataFrame.sum with axis=None is deprecated, in a future version this will reduce over both axes and return a scalar. To retain the old behavior, pass axis=0 (or do not pass axis)
return reduction(axis=axis, out=out, **passkwargs)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-21-6dabb3fee1af> in ?()
----> 1 sum_tab = ct.generate_summary()
~\anaconda3\Lib\site-packages\fouriertransform\crosstable.py in ?(self)
462 ----------
463 Santi-Temkiv et al. (2013), PLoS One, doi:10.1371/journal.pone.0053550.
464 '''
465
--> 466 sum_df = _gen_sum_tab(self)
467
468 return sum_df
~\anaconda3\Lib\site-packages\fouriertransform\crosstable_helper.py in ?(ct)
1022
1023 sum_df['AImod_RA'] = \
1024 np.sum(ct.intensities.multiply(ct.AImod, axis = 0))/tot_int
1025
-> 1026 sum_df[cls_mets] = _calc_pct(ct, cls_mets, ct.cmpd_class)
1027 sum_df[cat_mets] = _calc_pct(ct, cat_mets, ct.cmpd_cat)
1028
1029 return sum_df
~\anaconda3\Lib\site-packages\fouriertransform\crosstable_helper.py in ?(ct, cols, weights)
524 for n in names:
525
526 #extract compounds within class/category
527 ind = np.where(weights == n)[0]
--> 528 cforms = df.iloc[ind]
529
530 #calculate class/category formula numbers and intensities
531 c_N = np.sum(cforms > 0)
~\anaconda3\Lib\site-packages\pandas\core\generic.py in ?(self, name)
6200 and name not in self._accessors
6201 and self._info_axis._can_hold_identifiers_and_holds_name(name)
6202 ):
6203 return self[name]
-> 6204 return object.__getattribute__(self, name)
AttributeError: 'DataFrame' object has no attribute 'ix'
I think if I can clear this attribute error, I should be able to get the summary table. I'm happy to provide the data files and script files I'm working with if that would be more helpful.
EDIT: reloading the module worked! I didn't realize that was an option.