8

私は、企業向けにYahoo Financeから有形の価格/本をほとんど生成する、かなり壊れたコードをいくつか持っています(と呼ばれる優れたモジュールystockquoteは、無形の価格/本価値をすでに取得しています)。

私の問題はこれです:

計算の変数の 1 つである未発行株数については、 10.89B4.9Mなどの文字列を取得しています。ここで、BMはそれぞれ10 億100 万を表します。それらを数値に変換するのに問題があります。ここにいます:

shares=''.join(node.findAll(text=True)).strip().replace('M','000000').replace('B','000000000').replace('.','') for node in soup2.findAll('td')[110:112]

これはかなり面倒ですが、代わりに

.replace('M','000000').replace('B','000000000').replace('.','') 

変数で正規表現を使用していました。問題は単純に、どの正規表現と変数かということだと思います。他の提案も良いです。

編集:

具体的には、小数点以下が 0、1、または 2 の数値で機能するものを望んでいますが、これらの回答はすべて役に立ちます。

4

5 に答える 5

19
>>> from decimal import Decimal
>>> d = {
        'M': 6,
        'B': 9
}
>>> def text_to_num(text):
        if text[-1] in d:
            num, magnitude = text[:-1], text[-1]
            return Decimal(num) * 10 ** d[magnitude]
        else:
            return Decimal(text)

>>> text_to_num('3.17B')
Decimal('3170000000.00')
>>> text_to_num('4M')
Decimal('4000000')
>>> text_to_num('4.1234567891234B')
Decimal('4123456789.1234000000000')

必要に応じて結果を取得することもできint()ます

于 2012-08-10T06:40:01.323 に答える
4

数値を float として解析し、乗数マッピングを使用します。

multipliers = dict(M=10**6, B=10**9)
def sharesNumber(nodeText):
    nodeText = nodeText.strip()
    mult = 1
    if nodeText[-1] in multipliers:
        mult = multipliers[nodeText[-1]]
        nodeText = nodeText[:-1]
    return float(nodeText) * mult
于 2012-08-10T06:36:44.727 に答える
3
num_replace = {
    'B' : 1000000000,
    'M' : 1000000,
}

a = "4.9M" 
b = "10.89B" 

def pure_number(s):
    mult = 1.0
    while s[-1] in num_replace:
        mult *= num_replace[s[-1]]
        s = s[:-1]
    return float(s) * mult 

pure_number(a) # 4900000.0
pure_number(b) # 10890000000.0

これは、次のような愚かさで機能します。

pure_number("5.2MB") # 5200000000000000.0

また、ディクショナリのアプローチにより、維持しやすい方法で必要な数のサフィックスを追加できます。また、dict キーを 1 つの大文字化形式で表現し、それを一致させるために.lower()or.upper()を実行することで、サフィックスをより寛大にすることができます。

于 2012-08-10T06:43:02.850 に答える
2
num_replace = {
    'B' : 'e9',
    'M' : 'e6',
}

def str_to_num(s):
    if s[-1] in num_replace:
        s = s[:-1]+num_replace[s[-1]]
    return int(float(s))

>>> str_to_num('3.71B')
3710000000L
>>> str_to_num('4M')
4000000

だから'3.71B'-> '3.71e9'->3710000000Lなど。

于 2012-08-10T06:54:14.363 に答える
1

これはevalを安全に使用する機会になるかもしれません!! :-)

次のフラグメントについて考えてみます。

>>> d = { "B" :' * 1e9', "M" : '* 1e6'}
>>> s = "1.493B"
>>> ll = [d.get(c, c) for c in s]
>>> eval(''.join(ll), {}, {})
1493000000.0

今、それをすべてまとめて、きちんとした1つのライナーにします。

d = { "B" :' * 1e9', "M" : '* 1e6'}

def human_to_int(s):
    return eval(''.join([d.get(c, c) for c in s]), {}, {})

print human_to_int('1.439B')
print human_to_int('1.23456789M')

恩返し:

1439000000.0
1234567.89
于 2012-08-10T08:37:25.440 に答える