python-3.x 在pandas Dataframe 中使用什么dtype来表示货币?

2lpgd968  于 2023-04-08  发布在  Python
关注(0)|答案(4)|浏览(149)

所以我有一个Pandas数据框对象,它的货币列有两位小数,比如“133.04”。没有三位或更多小数位的数字,只有两位。

My Try:Decimal模块

我试过使用十进制模块,但当我试着像这样重新采样时

gr_by_price = df['price'].resample(timeframe, how='ohlc')

我明白

pandas.core.groupby.DataError: No numeric types to aggregate

在此之前我检查了dtype

print(type(df['price'][0]))
<class 'decimal.Decimal'>

我是这个库和货币处理的新手,也许Decimal不是正确的选择?我该怎么办?
如果我把这个列转换为<class 'numpy.float64'>,一切都正常。
更新:目前我正在使用这种方法

d.Decimal("%0.2f" % float(d.Decimal("1.04")))
Decimal('1.04')

this question开始

ogsagwnx

ogsagwnx1#

您需要区分内部值表示和表示方式(阅读有关MVC here的更多信息)。正如您所说,您不需要其他类型的浮点数表示,我建议继续使用常规float进行内部表示和数学(它是IEEE-754标准),只需添加这一行

pd.options.display.float_format = '{:6.2f}'.format

这将使所有打印的值自动四舍五入到第二位数,而不会实际更改它们的值。(pdpandas的常见别名)。

62lalag4

62lalag42#

Decimal似乎是一个非常合理的用例表示。这里的潜在问题是pandas中的ohlc聚合器调用cython以提高速度,我假设cython不能接受Decimals。请参阅:https://github.com/pandas-dev/pandas/blob/v0.20.3/pandas/core/groupby.py#L1203-L1212
欧洲工商管理学院认为,最直接的方法是自己编写ohlc,这样它就可以对小数进行操作

In [89]: index = pd.date_range('1/1/2000', periods=9, freq='T')

In [90]: series = pd.Series(np.linspace(0, 2, 9), index=index)

In [91]: series.resample('3T').ohlc()
Out[91]:
                     open  high   low  close
2000-01-01 00:00:00  0.00  0.50  0.00   0.50
2000-01-01 00:03:00  0.75  1.25  0.75   1.25
2000-01-01 00:06:00  1.50  2.00  1.50   2.00

In [92]: decimal_series = pd.Series([Decimal(x) for x in np.linspace(0, 2, 9)], index=index)

In [93]: def ohlc(x):
    ...:     x = x[x.notnull()]
    ...:     if x.empty:
    ...:         return pd.Series({'open': np.nan, 'high': np.nan, 'low': np.nan, 'close': np.nan})
    ...:     return pd.Series({'open': x.iloc[0], 'high': x.max(), 'low': x.min(), 'close':x.iloc[-1]})
    ...:
In [107]: decimal_series.resample('3T').apply(ohlc).unstack()
Out[107]:
                    close  high   low  open
2000-01-01 00:00:00   0.5   0.5     0     0
2000-01-01 00:03:00  1.25  1.25  0.75  0.75
2000-01-01 00:06:00     2     2   1.5   1.5
0vvn1miw

0vvn1miw3#

我们遇到了类似的问题;最好的方法是将它乘以100并表示为整数(对于打印/外部选项使用/100)。这将导致快速,精确的计算(1 + 2 == 30.1 + 0.2 != 0.3不同)

hpcdzsge

hpcdzsge4#

我过去也遇到过这个问题,我最终使用的解决方案是将货币表示为最低面额的倍数(即,一美分代表美元)。因此,类型将是int。这种方法的优点是,正如这里已经提到的,您可以执行无损整数计算。

Price (currency) = Multiplyer * Sub_unit

例如,对于美元,价格单位是美元,子单位是1美分,乘数为100。
另一个方面我想提的是,这在不同货币之间都很有效。例如,日元的最小面额是1日元,在这种情况下乘数是1。印度尼西亚卢比的最小面额是1000卢比,因此乘数也可以是1。您只需记住每种货币的乘数。
事实上,你甚至可以创建一个自定义类来为你 Package 这个转换,这可能是最方便的解决方案。

相关问题