Pandas version checks
-
[x] I have checked that this issue has not already been reported.
-
[x] I have confirmed this bug exists on the latest version of pandas.
-
[x] I have confirmed this bug exists on the main branch of pandas.
Reproducible Example
import pandas as pd
df = pd.DataFrame(np.arange(12).reshape(3,4))
s = [1,pd.NA,3]
df.mul(s, axis="columns", fill_value=0)
Issue Description
It raise error: fill_value=0 is not supported
Expected Behavior
It should return the result with filled NA value of 0
Installed Versions
Comment From: sanggon6107
Hi @TungPhaSanh ,
It seems the example code doesn't work because s
only has 3 elements - I think it needs 4.
I have tried this on the main branch, but mul
seems to work fine when fill_value=0
.
>>> import pandas as pd
>>> import numpy as np
>>> df = pd.DataFrame(np.arange(12).reshape(3,4))
>>> df
0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
>>> s = [1,pd.NA,3, 4]
>>> s
[1, <NA>, 3, 4]
>>> df.mul(s, axis="columns", fill_value=0)
0 1 2 3
0 0 0 6 12
1 4 0 18 28
2 8 0 30 44
Comment From: TungPhaSanh
Thanks @sanggon6107
My bad. Sorry with my example, the true one is:
import pandas as pd df = pd.DataFrame(np.arange(12).reshape(3,4)) s = [1,pd.NA,3] df.mul(s, axis="index", fill_value=0) # index instead of columns
I have try it, it is okay, but sometimes in my project it raise error fill_value=0 is not supported. I have to fillna first before doing multiplication.
Comment From: asishm
Thanks for the report. Your example doesn't reproduce for me on latest release (2.3.0) with axis='index'
.
Can you confirm your example provided currently fails for you and if so, please provide the full traceback. If not, please update your post with a reproducible example. Thanks!
>>> df
0 1 2 3
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
>>> s = [1,pd.NA,3]
>>> df.mul(s, axis="index", fill_value=0)
0 1 2 3
0 0 1 2 3
1 0 0 0 0
2 24 27 30 33
>>> pd.__version__
'2.3.0'
Comment From: TungPhaSanh
Hi @asishm ,
I have face this error in my project, when I try it. Here is my code:
adjusted_data[["Open", "High", "Low", "Close"]] = adjusted_data[
["Open", "High", "Low", "Close"]
].mul(adjusted_data["Multiplier"], axis=0, fill_value=1)
---------------------------------------------------------------------------
NotImplementedError Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_9980\1777838207.py in ?()
2 listed_data, adjustment_multiplier, left_on="Ticker", right_index=True, how="left"
3 )
4 adjusted_data[["Open", "High", "Low", "Close"]] = adjusted_data[
5 ["Open", "High", "Low", "Close"]
----> 6 ].mul(adjusted_data["Multiplier"], axis=0, fill_value=1)
7 adjusted_data
~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\site-packages\pandas\core\frame.py in ?(self, other, axis, level, fill_value)
8386 @Appender(ops.make_flex_doc("mul", "dataframe"))
8387 def mul(
8388 self, other, axis: Axis = "columns", level=None, fill_value=None
8389 ) -> DataFrame:
-> 8390 return self._flex_arith_method(
8391 other, operator.mul, level=level, fill_value=fill_value, axis=axis
8392 )
~\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\site-packages\pandas\core\frame.py in ?(self, other, op, axis, level, fill_value)
8264
8265 if isinstance(other, Series) and fill_value is not None:
8266 # TODO: We could allow this in cases where we end up going
8267 # through the DataFrame path
-> 8268 raise NotImplementedError(f"fill_value {fill_value} not supported.")
8269
8270 other = ops.maybe_prepare_scalar_for_op(other, self.shape)
8271 self, other = self._align_for_op(other, axis, flex=True, level=level)
NotImplementedError: fill_value 1 not supported.
For more information: adjusted_data
is a DataFrame of 9 columns * 4,000,000 rows.
But when I try the following:
adjusted_data[["Open", "High", "Low", "Close"]] = adjusted_data[
["Open", "High", "Low", "Close"]
].mul(adjusted_data["Multiplier"].fillna(1), axis=0)
it is okay.
Comment From: eicchen
I was able to replicate the issue and can takeover the ticket
Comment From: eicchen
@jbrockmendel Do you remember if there was a specific reason fill_value was initially excluded from working on series for DataFrame.mul? Because the functionality seems to already be there barring the check that's throwing the error above.
Comment From: jbrockmendel
It was like this when I got here. I don't think anyone would mind adding support.
Comment From: eicchen
@jbrockmendel Do you know what the TODO comment there could mean then? Not sure that I fully understand what the original reasoning for it could be
Comment From: jbrockmendel
i suspect the idea was that depending on the axis we could do other = DataFrame({x: other for x in self.columns})
(not exactly that bc of non-unique columns)
Comment From: eicchen
@jbrockmendel after tinkering around, I think that the fill_value problem was fixed in the PR that I ended up closing. Operations not supporting 1-D EAs feels like a separate issue to me. My proposal is that I put in a PR just tackling the fill_value change and then put a separate one in for 1-D EA operations. What do you think?
Comment From: jbrockmendel
IIRC that PR was almost right and could get there with a little work. you're welcome to reopen it and we can talk through a fix.
Comment From: eicchen
Oop, I got completely sidetracked and end up working on getting 1D EAs to work with operations. Ill reopen the PR and we can move the discussion over there