2

csvを1行ずつ読んでいます。CSVは次のようになります。

29.781646
29.781646
42.698079
43.346914
44.369203
45.006459
45.006459
39.316758

2つの数字がまったく同じである場合、1つを少し変更したいと思います。

たとえば、2つの値があり29.781646、1つを次のように変更したいと思います。29.781645

csvに含まれるもの:

29.781646
29.781646
29.781646

次に、次のように変更します。

29.781646
29.781645
29.781644

これを効率的に実施するためのご指導をいただければ幸いです。

これを倍数で実行したいことに注意してください0.000001

4

3 に答える 3

6

ファイルを1行ずつ繰り返し処理し、を使用して表示された値を追跡setし、値がすでに。にある場合は値を減らすことができますset

大まかな例:

seen = set()
with open('test.csv') as input, open('test_out.csv', 'w') as output:
    for line in input:
        value = float(line)
        while value in seen:
            value -= 0.000001
        seen.add(value)
        output.write(str(value) + '\n')

setaはO(1)ルックアップを提供するため、これは効率的です


とにかく同じファイルに値を書き戻す場合は、fileinputモジュールを使用できます。

import fileinput

seen = set()
for line in fileinput.FileInput('test.csv', inplace=True):
    value = float(line)
    while value in seen:
        value -= 0.000001
    seen.add(value)
    print str(value).strip()

編集

浮動小数点の問題に関するeumiroのコメントに対処するには:

decimalモジュールを使用するか、を使用する代わりにDecimal、値をwith / byで乗算/除算して、操作することができます。私が書いたように、これは単なる大まかな例です:-)1000000intfloat

于 2012-08-29T08:09:08.653 に答える
1
>>> s = """29.781646
29.781646
42.698079
43.346914
44.369203
45.006459
45.006459
39.316758
"""
>>> d = {}
>>> for nb in [float(l) for l in s.split('\n') if l]:
    # Create a dict of repetitions, to decrease by the number of times already seen
    if nb not in d:
        d[nb] = 0
        print nb
    else:
        rep = d[nb]
        d[nb] = rep + 1
        print nb - d[nb] * 0.000001


29.781646
29.781645
42.698079
43.346914
44.369203
45.006459
45.006458
39.316758
>>> 
于 2012-08-29T08:15:52.723 に答える
1

BigYellowCactusに基づいていますが、何度も変更されるフロートにエラーがどのように蓄積されるかについてのeumiroのコメントに対応しています。

seen = set() with open('test.csv') as input, open('test_out.csv', 'w') as output:
    for line in input:
        value = float(line)
        modifier = 1

        while True
            new_value = value - (modifier * 0.000001)
            modifier += 1
            if not new_value in seen:
                break

        seen.add(new_value)
        output.write(str(value) + '\n')
于 2012-08-29T08:25:58.180 に答える