Pandas divide returns dataframe with all NaNs - python

I have 2 Pandas Dataframes, totals and medal_counts. The head info is given below.
print(medal_counts.head())
NOC AFG AHO ALG ANZ ARG ARM AUS AUT AZE BAH ... URS URU \
Edition ...
1896 NaN NaN NaN NaN NaN NaN 2.0 5.0 NaN NaN ... NaN NaN
1900 NaN NaN NaN NaN NaN NaN 5.0 6.0 NaN NaN ... NaN NaN
1904 NaN NaN NaN NaN NaN NaN NaN 1.0 NaN NaN ... NaN NaN
1908 NaN NaN NaN 19.0 NaN NaN NaN 1.0 NaN NaN ... NaN NaN
1912 NaN NaN NaN 10.0 NaN NaN NaN 14.0 NaN NaN ... NaN NaN
NOC USA UZB VEN VIE YUG ZAM ZIM ZZX
Edition
1896 20.0 NaN NaN NaN NaN NaN NaN 6.0
1900 55.0 NaN NaN NaN NaN NaN NaN 34.0
1904 394.0 NaN NaN NaN NaN NaN NaN 8.0
1908 63.0 NaN NaN NaN NaN NaN NaN NaN
1912 101.0 NaN NaN NaN NaN NaN NaN NaN
[5 rows x 138 columns]
print(totals.head())
Edition
1896 151
1900 512
1904 470
1908 804
1912 885
Name: Grand Total, dtype: int64
When I try divide 'medal_counts' using 'totals' row-wise using divide method, why I am getting all NaNs though there are some clear values in medal_counts, such as in 1896 for AUS, AUT, USA & ZZX.
fractions = medal_counts.divide(totals, axis='rows')
print(fractions.head())
NOC AFG AHO ALG ANZ ARG ARM AUS AUT AZE BAH ... URS URU USA \
Edition ...
1896 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN
1900 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN
1904 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN
1908 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN
1912 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN
NOC UZB VEN VIE YUG ZAM ZIM ZZX
Edition
1896 NaN NaN NaN NaN NaN NaN NaN
1900 NaN NaN NaN NaN NaN NaN NaN
1904 NaN NaN NaN NaN NaN NaN NaN
1908 NaN NaN NaN NaN NaN NaN NaN
1912 NaN NaN NaN NaN NaN NaN NaN
Appreciate clarifications.

Below transformation works.
totals = totals.values
fractions = medal_counts.divide(totals, axis='rows')

When you use pandas divide:
df.divide(other)
The type of other can be : scalar, sequence, Series, or DataFrame.
In your case, if you would specify a series it would work:
fractions = medal_counts.divide(totals['Edition'], axis='rows')
So, when should we use dataframe?
If you the other dataframe`s shape is the same as df.
For example:
df = pd.DataFrame({'angles': [0, 3, 4],
'degrees': [360, 180, 360]},
index=['circle', 'triangle', 'rectangle'])
df
angles degrees
circle 0 360
triangle 3 180
rectangle 4 360
you can do:
>>> df.divide(df+1, axis='index')
angles degrees
circle 0.00 0.997230
triangle 0.75 0.994475
rectangle 0.80 0.997230
Why converting to numpy array is not safe?
If your rows are shuffled you will get the wrong answer:
df
angles degrees
circle 0 360
triangle 3 180
rectangle 4 360
shuffle the angles column and create a new df:
df2 = df[['angles']].sample(frac=1)
df2
angles
triangle 3
circle 0
rectangle 4
The desired output:
>>> df.divide(df2['angles'], axis='rows')
angles degrees
circle NaN inf
rectangle 1.0 90.0
triangle 1.0 60.0
and the output using numpy array:
>>> df.divide(df2['angles'].values, axis='rows')
angles degrees
circle 0.0 120.0
triangle inf inf
rectangle 1.0 90.0

Related

Changing the Values of a Multi-Index Dataframe

I have a multi-index dataframe that is set up as follows:
index = pd.MultiIndex.from_product([['A','B','C'], ['x','y', 'z']])
multi_index = pd.DataFrame(np.nan, index=np.arange(10), columns=index)
Which produces the following output:
A B C
x y z x y z x y z
0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN NaN NaN NaN NaN
5 NaN NaN NaN NaN NaN NaN NaN NaN NaN
6 NaN NaN NaN NaN NaN NaN NaN NaN NaN
7 NaN NaN NaN NaN NaN NaN NaN NaN NaN
8 NaN NaN NaN NaN NaN NaN NaN NaN NaN
9 NaN NaN NaN NaN NaN NaN NaN NaN NaN
I am trying to fill the values of the multi-index data frame with values. As a toy example, what I've tried to do is change the value of ['A','x',0] as follows:
multi_index['A']['x'].loc[0] = 65.2
However, I receive a 'SettingWithCopyWarning', which makes sense to me. I've also tried
multi_index['A'].iloc[[1],0] = 65.2
and received the same warning.
Is there a way one can change the values of a multi-index dataframe on a entry-by-entry basis? I.E changing the 0th index of ['A','x']?
Try:
multi_index.loc[0, ('A', 'x')] = 65.2
You can use tuples with loc for index labelling to access your multiindex columns or rows.
Or you can use iloc like this using integer index position selection, for example 2 here is the third column:
multi_index.iloc[0, 2] = 70.3
Output:
A B C
x y z x y z x y z
0 65.2 NaN 70.3 NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN NaN NaN NaN NaN
5 NaN NaN NaN NaN NaN NaN NaN NaN NaN
6 NaN NaN NaN NaN NaN NaN NaN NaN NaN
7 NaN NaN NaN NaN NaN NaN NaN NaN NaN
8 NaN NaN NaN NaN NaN NaN NaN NaN NaN
9 NaN NaN NaN NaN NaN NaN NaN NaN NaN

Convert dictionary into Pandas dataframe

I have a dictionary that looks like this:
my_dict = {'product1' : [1, 511, 31, 222, 9020], 'product2' : [92, 511, 314, 4324], 'product3' : [40, 17, 4324]}
I want to create a dataframe that has the products as the index and the column names should be a range from 1 - 10 000, and if the value list associated to the product has the number it should be marked as a 1 or True in the column for the respective number.
1 2 3 ... 4324 .... 9020
product1 1 1
product2 1
product3 1
This entire dictionary has 80 products, each associated with a list of 0 to maybe a maximum of 50 numbers. The numbers could range between 1 and 10 000.
I would really appreciate any hints, I haven't managed to found a good way. I know I can create a dataframe from dictionary with pandas.DataFrame.from_dict() but it doesn't really do what I want.
I did a "ugly" solution, but I'm guessing this is not best practice or pythonic:
column_names = list(range(0,10000))
df = pd.DataFrame(columns = column_names)
for k, v in my_dict.items():
x = pd.Series(np.ones(len(v), dtype=int), index =v, name=k)
df = df.append(x)
print(df.head())
which outputs
0 1 2 3 4 5 6 7 8 9 ... \
product1 NaN 1.0 NaN NaN NaN NaN NaN NaN NaN NaN ...
product2 NaN NaN NaN 1.0 NaN NaN NaN NaN NaN NaN ...
product3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ...
9990 9991 9992 9993 9994 9995 9996 9997 9998 9999
product1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
product2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
product3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
[3 rows x 10000 columns]
One way could be to use start by constructing a dataframe from the dictionary via the alternative constructor pd.DataFrame.from_dict, which handles arrays of different length setting orient='index'.
df = pd.DataFrame.from_dict(my_dict, orient='index')
Then usepd.get_dummies over all columns:
df = pd.get_dummies(df, columns=df.columns, prefix='', prefix_sep='')
df.columns = pd.to_numeric(df.columns).astype(int)
df.T.groupby(level=0).max().T.reindex(range(df.columns.max()), axis=1)
0 1 2 3 4 5 6 7 8 9 ... \
product1 NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN ...
product2 NaN 0 NaN NaN NaN NaN NaN NaN NaN NaN ...
product3 NaN 0 NaN NaN NaN NaN NaN NaN NaN NaN ...
9010 9011 9012 9013 9014 9015 9016 9017 9018 9019
product1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
product2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
product3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Use the from_dict method with orient='index':
my_dict = {
'product1' : [1, 511, 31, 222, 9020],
'product2' : [92, 511, 314, 4324],
'product3' : [40, 17, 4324]
}
df = pd.DataFrame.from_dict(my_dict, orient='index')
print(df)
Output:
0 1 2 3 4
product1 1 511 31 222.0 9020.0
product2 92 511 314 4324.0 NaN
product3 40 17 4324 NaN NaN
Try this
import pandas as pd
import numpy as np
my_dict = {'product1' : [1, 511, 31, 222, 9020], 'product2' : [92, 511, 314, 4324], 'product3' : [40, 17, 4324]}
res = []
for x in my_dict:
arr = [np.nan] * 10000
for y in my_dict[x]:
arr[y - 1] = 1
res.append(arr)
df = pd.DataFrame(res, index=my_dict.keys())
print(df)
Output:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 ... 9750 9751 9752 9753 9754 9755 9756 9757 9758 9759 9760 9761 9762 9763 9764 9765 9766 9767 9768 9769 9770 9771 9772 9773 9774 9775 9776 9777 9778 9779 9780 9781 9782 9783 9784 9785 9786 9787 9788 9789 9790 9791 9792 9793 9794 9795 9796 9797 9798 9799 9800 9801 9802 9803 9804 9805 9806 9807 9808 9809 9810 9811 9812 9813 9814 9815 9816 9817 9818 9819 9820 9821 9822 9823 9824 9825 9826 9827 9828 9829 \
product1 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
product2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
product3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
9830 9831 9832 9833 9834 9835 9836 9837 9838 9839 9840 9841 9842 9843 9844 9845 9846 9847 9848 9849 9850 9851 9852 9853 9854 9855 9856 9857 9858 9859 9860 9861 9862 9863 9864 9865 9866 9867 9868 9869 9870 9871 9872 9873 9874 9875 9876 9877 9878 9879 9880 9881 9882 9883 9884 9885 9886 9887 9888 9889 9890 9891 9892 9893 9894 9895 9896 9897 9898 9899 9900 9901 9902 9903 9904 9905 9906 9907 9908 9909 9910 9911 9912 9913 9914 9915 9916 9917 9918 9919 9920 9921 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9954 9955 9956 9957 9958 9959 9960 9961 9962 9963 9964 9965 9966 9967 9968 9969 9970 9971 9972 9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992 9993 9994 9995 9996 9997 9998 9999
product1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
product2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
product3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

Cubic interpolation in Pandas raises ValueError: The number of derivatives at boundaries does not match: expected 2, got 0+0

I am getting the following error
ValueError: The number of derivatives at boundaries does not match: expected 2, got 0+0
while trying to use cubic interpolation in pandas on a 2d matrix.
mat = pd.read_csv("m.csv")
mat = mat.interpolate(method='cubic')
Csv to reproduce can be downloaded here
I think the issue is that you need at least 4 points for cubic interpolation, look at this : question. It works for column 0:
mat['0'].interpolate(method='cubic', inplace=True)
print(mat)
0 1 2 3 4 5 6 7 8 9 10 11 12 13
0 -0.000347 NaN 0.002546 NaN 0.001891 NaN NaN NaN 0.001845 NaN 0.001507 NaN 0.000452 NaN
1 0.000210 NaN NaN NaN NaN NaN NaN 0.002109 NaN NaN NaN NaN NaN NaN
2 0.000438 NaN NaN NaN NaN NaN NaN NaN NaN NaN 0.004112 NaN NaN NaN
3 0.000419 NaN NaN 0.001114 NaN 0.000599 0.003813 NaN 0.003342 NaN NaN NaN 0.001095 NaN
4 0.000240 0.001143 NaN 0.002955 NaN 0.004867 0.000857 NaN 0.002584 NaN NaN 0.002765 -0.000012 NaN
5 -0.000016 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6 -0.000264 NaN NaN -0.000257 NaN 0.002049 0.001710 NaN -0.000041 NaN NaN NaN 0.000934 NaN
7 -0.000419 0.003044 NaN NaN NaN NaN NaN NaN NaN NaN 0.001225 NaN NaN NaN
8 -0.000397 NaN 0.001417 NaN NaN NaN NaN 0.001647 NaN NaN NaN NaN NaN NaN
9 -0.000169 NaN NaN NaN NaN 0.000154 NaN NaN NaN 0.000424 -0.000507 NaN 0.000550 NaN
10 0.000072 NaN NaN 0.000768 NaN NaN 0.000315 NaN NaN 0.000055 -0.000477 NaN 0.002413 NaN
11 0.000078 NaN NaN NaN NaN 0.000512 NaN NaN NaN NaN NaN NaN NaN NaN
12 -0.000399 NaN NaN NaN NaN 0.003461 0.001000 NaN NaN NaN NaN NaN 0.001112 NaN
13 -0.001608 NaN 0.001928 NaN NaN NaN NaN NaN NaN 0.001780 0.002132 NaN NaN NaN

Filtering from pandas pivot table by value in a row

I created a (large) sparse matrix by a pivot table.
UserId ...
1 5.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN ...
2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ...
3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ...
4 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ...
5 NaN NaN NaN NaN NaN 2.0 NaN NaN NaN NaN ...
... ... ... ... ... ... ... ... ... ... ... ...
6036 NaN NaN NaN 2.0 NaN 3.0 NaN NaN NaN NaN ...
6037 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ...
6038 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ...
6039 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ...
6040 3.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN ...
MovieId 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952
UserId
1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
4 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... ... ...
6036 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6037 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6038 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6039 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
6040 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Now, I am looking for a way for, given a row index (e.g. 1) select all index whose values are > 4.0. Is there a simple way to do so?.
I tried the following
df.loc[1] >= 4.0
however what I get is
MovieId
1 True
2 False
3 False
4 False
5 False
...
3948 False
3949 False
3950 False
3951 False
3952 False
Name: 1, Length: 3706, dtype: bool
meaning I am almost there, but not quite. How do I extract the indices corresponding to True?
You can chain two loc selections, the first selects the rows based on label, the second will use a function to subset the columns based on your condition. Or you could use a single nested loc, where the columns mask also calls .loc
import numpy as np
import pandas as pd
np.random.seed(42)
df = pd.DataFrame(np.random.choice([1, np.NaN, 5], p=[.2, .7, .1], size=(2, 40)))
df.loc[1].loc[lambda x: x >= 4]
#or
df.loc[1, df.loc[1] >= 4]
#3 5.0
#10 5.0
#12 5.0
#15 5.0
#29 5.0
#Name: 1, dtype: float64

pandas - efficiently computing combinatoric arithmetic

I have a DataFrame that look like such:
BestBid BestOffer
Strike
800 1253.900024 1256.599976
900 1154.199951 1156.800049
1000 1054.400024 1056.900024
1050 1004.500000 1007.000000
1100 954.599976 957.000000
... ...
2350 0.050000 0.400000
2400 0.000000 0.200000
2450 0.000000 0.600000
2500 0.000000 0.600000
3000 0.000000 0.600000
And I want to compute a grid of all pairwise combinations of the index, and compute some arithmetic operation on the pairs. My code below is how I do it iteratively (and slowly):
output = pd.DataFrame(index=df.index, columns=df.index)
for pair in itertools.combinations(df.index, 2):
if pair[0] >= pair[1]:
continue
low= pair[0]
high= pair[1]
spread = df.loc[high, 'BestBid'] - df.loc[low, 'BestOffer']
output.loc[low, high] = spread
output ends up looking like:
800 900 1000 1050 1100 1125 1150 1175 1200 1220 1225 1240 ... 2220 2225 2230 2240 2250 2275 2300 2350 2400 2450 2500 3000
800 NaN -102.4 -202.2 -252.1 -302 -326.9 -352.1 -376.8 -401.7 -421.7 -426.7 -441.6 ... -1256.05 -1255.85 -1256.25 -1256.45 -1256.5 -1256.45 -1256.55 -1256.55 -1256.6 -1256.6 -1256.6 -1256.6
900 NaN NaN -102.4 -152.3 -202.2 -227.1 -252.3 -277 -301.9 -321.9 -326.9 -341.8 ... -1156.25 -1156.05 -1156.45 -1156.65 -1156.7 -1156.65 -1156.75 -1156.75 -1156.8 -1156.8 -1156.8 -1156.8
1000 NaN NaN NaN -52.4 -102.3 -127.2 -152.4 -177.1 -202 -222 -227 -241.9 ... -1056.35 -1056.15 -1056.55 -1056.75 -1056.8 -1056.75 -1056.85 -1056.85 -1056.9 -1056.9 -1056.9 -1056.9
1050 NaN NaN NaN NaN -52.4 -77.3 -102.5 -127.2 -152.1 -172.1 -177.1 -192 ... -1006.45 -1006.25 -1006.65 -1006.85 -1006.9 -1006.85 -1006.95 -1006.95 -1007 -1007 -1007 -1007
1100 NaN NaN NaN NaN NaN -27.3 -52.5 -77.2 -102.1 -122.1 -127.1 -142 ... -956.45 -956.25 -956.65 -956.85 -956.9 -956.85 -956.95 -956.95 -957 -957 -957 -957
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2350 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN -0.4 -0.4 -0.4 -0.4
2400 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN -0.2 -0.2 -0.2
2450 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN -0.6 -0.6
2500 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN -0.6
3000 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Note that I make it slightly faster by not doing the operation if the first element of the pair is larger. This is essentially n^2 computation time, is there any faster or vectorized way of doing this in pandas?
numpy allows you do do these calculations without a loop. Here we use an outer subtraction to get all pairwise differences. Then mask the lower triangle.
import pandas as pd
import numpy as np
df1 = pd.DataFrame(-1*np.subtract.outer(df['BestOffer'].to_numpy(),
df['BestBid'].to_numpy()),
index=df.index.to_numpy(),
columns=df.index.to_numpy())
# `NaN` the lower triangle
df1 = df1.mask(np.tril(np.ones(df1.shape)).astype(bool))
800 900 1000 1050 1100 2350 2400 2450 2500 3000
800 NaN -102.400025 -202.199952 -252.099976 -302.000000 -1256.549976 -1256.599976 -1256.599976 -1256.599976 -1256.599976
900 NaN NaN -102.400025 -152.300049 -202.200073 -1156.750049 -1156.800049 -1156.800049 -1156.800049 -1156.800049
1000 NaN NaN NaN -52.400024 -102.300048 -1056.850024 -1056.900024 -1056.900024 -1056.900024 -1056.900024
1050 NaN NaN NaN NaN -52.400024 -1006.950000 -1007.000000 -1007.000000 -1007.000000 -1007.000000
1100 NaN NaN NaN NaN NaN -956.950000 -957.000000 -957.000000 -957.000000 -957.000000
2350 NaN NaN NaN NaN NaN NaN -0.400000 -0.400000 -0.400000 -0.400000
2400 NaN NaN NaN NaN NaN NaN NaN -0.200000 -0.200000 -0.200000
2450 NaN NaN NaN NaN NaN NaN NaN NaN -0.600000 -0.600000
2500 NaN NaN NaN NaN NaN NaN NaN NaN NaN -0.600000
3000 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
IIUC the calculation is BestBid minus BestOffer for each combination of values in Strike? If so this is a way I came up with that should be faster that basically constructs a pivot table from scratch:
pt = pd.DataFrame(index=df.index, columns=df.index)
for column in pt.columns:
pt[column] = df.loc[column, "BestBid"] - df["BestOffer"]

Categories

Resources