Pandas脚本将数字修改为长浮点数,甚至不应修改该列/元素

时间:2013-11-11 17:45:50

标签: python python-2.7 csv pandas

我下面有一个pandas脚本让我头疼,因为它不断修改我的数据,下面的例子可以100%完美地重新创建问题。 (让我永远找出造成这个问题的原因)

基本上,如果您将原始文件与修改后的testing2.csv进行比较,您会看到第一行中的数字如0.357变成:0.35700000000000004但是第2行的数字0.1128根本不会改变......

NOT 应该修改这些数字,它们应该都是原样。

testing.py

import re
import pandas
# each block in the text file will be one element of this list
matchers = [[]]
i = 0 
with open('testing.txt') as infile:
    for line in infile:
        line = line.strip()
        # Blocks are seperated by blank lines
        if len(line) == 0:
            i += 1
            matchers.append([])
            # assume there are always two blank lines between items 
            # and just skip to the lext line
            infile.next()
            continue
        matchers[i].append(line)


# This regular expression matches the variable number of students in each block
studentlike = re.compile('(\d+) (.+) (\d+/\d+)')
# These are the names of the fields we expect at the end of each block
datanames = ['Data', 'misc2', 'bla3']
# We will build a table containing a list of elements for each student
table = []
for matcher in matchers:
    # We use an iterator over the block lines to make indexing simpler
    it = iter(matcher)
    # The first two elements are match values
    m1, m2 = it.next(), it.next()
    # then there are a number of students
    students = []
    for possiblestudent in it:
        m = studentlike.match(possiblestudent)
        if m:
            students.append(list(m.groups()))
        else:
            break
    # After the students come the data elements, which we read into a dictionary
    # We also add in the last possible student line as that didn't match the student re
    dataitems = dict(item.split() for item in [possiblestudent] + list(it))
    # Finally we construct the table
    for student in students:
        # We use the dictionary .get() method to return blanks for the missing fields
        table.append([m1, m2] + student + [dataitems.get(d, '') for d in datanames])

textcols = ['MATCH2', 'MATCH1', 'TITLE01', 'MATCH3', 'TITLE02', 'Data', 'misc2', 'bla3']
csvdata = pandas.read_csv('testing.csv')
textdata = pandas.DataFrame(table, columns=textcols)

# Add any new columns
newCols = textdata.columns - csvdata.columns
for c in newCols:
    csvdata[c] = None

mergecols = ['MATCH2', 'MATCH1', 'MATCH3']
csvdata.set_index(mergecols, inplace=True, drop=False)
textdata.set_index(mergecols, inplace=True,drop=False)
csvdata.update(textdata)
csvdata.to_csv('testing2.csv', index=False)

testing.csv

testing.txt

MData (N/A)
DMATCH1
3 Tommy 144512/23332
1 Jim 90000/222311
1 Elz M 90000/222311
1 Ben 90000/222311
Data $50.90
misc2 $10.40
bla3 $20.20


MData (B/B) 
DMATCH2
4 James Smith 2333/114441
4 Mike 90000/222311
4 Jessica Long 2333/114441
Data $50.90
bla3 $5.44

任何人都有任何想法如何解决这个问题?

提前致谢
- Hyflex

3 个答案:

答案 0 :(得分:2)

这看起来像是一个精确的问题。

尝试更改to_csv行以包含参数float_format='%.4f',该参数会将事物舍入到2位小数。

答案 1 :(得分:1)

Pandas支持两种基本数字类型:Int64和Float64。 Float64不会完全表示十进制值,因为它是浮点类型。你的选择是

  1. 按照@TomAugspurger的建议指定float_format(这可以按列方式或整个数据框完成
  2. 将列dtype转换为对象
  3. 选项2可以通过以下方式完成:

    df['col_name'] = df['col_name'].astype(object)
    

答案 2 :(得分:0)

试试这个:)

csvdata = pandas.read_csv('testing.csv', dtype={'TITLE5' : 'object', 'TITLE5.1' : 'object', 'TITLE5.2' : 'object', 'TITLE5.3' : 'object'})