连接已解析的csv文件时出现的结果不一致

时间:2016-02-07 10:45:07

标签: python pandas

我对以下问题感到困惑。我有一组csv文件,我会迭代解析。在收集列表中的数据帧之前,我将一些函数(简单为tmp_df*2)应用于每个tmp_df。乍一看,这一切都完美无缺,直到我意识到我与运行结果不一致。 例如,当我申请df.std()时,我可能会收到第一次运行:

In[2]:  df1.std()
Out[2]:
  some_int      15281.99
  some_float    5.302293

并且在第二次运行之后:

In[3]:  df2.std()
Out[3]:
  some_int      15281.99
  some_float    6.691013

扼杀,当我不操纵解析数据时(我只是注释掉tmp_df = tmp_df*2),我不会发现像这样的不一致。我还注意到,对于我有数据类型int的列,结果在运行之间是一致的,这不适用于floats。我怀疑它与精度点有关。我也无法确定它们如何变化的模式,可能是我连续两次或三次运行的结果相同。也许有人知道我在这里遗失了什么。我正在研究复制示例,我将尽快编辑,因为我无法共享基础数据。也许有人可以在此期间对此有所了解。我使用的是win8.1,pandas 17.1,python 3.4.3。

代码示例:

 import pandas as pd
 import numpy as np

 data_list = list()
 csv_files = ['a.csv', 'b.csv', 'c.csv']

 for csv_file in csv_files:

    #  load csv_file
    tmp_df = pd.read_csv(csv_file, index_col='ID', dtype=np.float64)

    # replace infs by na
    tmp_df.replace([np.inf, -np.inf], np.nan, inplace=True)

    # manipulate tmp_df
    tmp_df = tmp_df*2

    data_list.append(tmp_df)

df = pd.concat(data_list, ignore_index=True)
df.reset_index(inplace=True)

更新

在UX系统上运行相同的代码和数据非常正常。

编辑: 我设法重新创建了问题,它应该在win和ux上运行。我已经在win8.1上测试了with_function=True(通常在1-5次运行后)遇到同样的问题,在ux上运行没有问题。 with_function=False在win和ux中没有差异。我也可以拒绝与intfloat问题相关的假设,因为模拟的int也不同......

以下是代码:

import pandas as pd
import numpy as np
from pathlib import Path
from tempfile import gettempdir


def simulate_csv_data(tmp_dir,num_files=5):
    """ simulate a csv files
    :param tmp_dir: Path, csv files are saved to
    :param num_files: int, how many csv files to simulate
    :return:
    """

    rows = 20000
    columns = 5
    np.random.seed(1282)

    for file_num in range(num_files):

        file_path = tmp_dir.joinpath(''.join(['df_', str(file_num), '.csv']))
        simulated_df = pd.DataFrame(np.random.standard_normal((rows, columns)))
        simulated_df['some_int'] = np.random.randint(0,100)
        simulated_df.to_csv(str(file_path))


def get_csv_data(tmp_dir,num_files=5, with_function=True):
    """ Collect various csv files and return a concatenated dfs
    :param tmp_dir: Path, csv files are saved to
    :param num_files: int, how many csv files to simulate
    :param with_function: Bool, apply function to tmp_dataframe
    :return:
    """

    data_list = list()

    for file_num in range(num_files):
        # current file path
        file_path = tmp_dir.joinpath(''.join(['df_', str(file_num), '.csv']))

        #  load csv_file
        tmp_df = pd.read_csv(str(file_path), dtype=np.float64)

        # replace infs by na
        tmp_df.replace([np.inf, -np.inf], np.nan, inplace=True)

        # apply function to tmp_dataframe
        if with_function:
            tmp_df = tmp_df*2

        data_list.append(tmp_df)

    df = pd.concat(data_list, ignore_index=True)
    df.reset_index(inplace=True)

    return df

def main():

    # INPUT ----------------------------------------------
    num_files = 5
    with_function = True
    max_comparisons = 50
    # ----------------------------------------------------

    tmp_dir = gettempdir()
    # use temporary "non_existing" dir for new file
    tmp_csv_folder = Path(tmp_dir).joinpath('csv_files_sdfs2eqqf')

    # if exists already don't simulate data/files again
    if tmp_csv_folder.exists() is False:
        tmp_csv_folder.mkdir()
        print('Simulating temp files...')
        simulate_csv_data(tmp_csv_folder, num_files)

    print('Getting benchmark data frame...')
    df1 = get_csv_data(tmp_csv_folder, num_files, with_function)
    df_is_same = True
    count_runs = 0

    # Run until different df is found or max runs exceeded
    print('Comparing data frames...')
    while df_is_same:
        # get another data frame
        df2 = get_csv_data(tmp_csv_folder, num_files, with_function)
        count_runs += 1
        # compare data frames
        if df1.equals(df2) is False:
            df_is_same = False
            print('Found unequal df after {} runs'.format(count_runs))
            # print out a standard deviations (arbitrary example)
            print('Std Run1: \n {}'.format(df1.std()))
            print('Std Run2: \n {}'.format(df2.std()))

        if count_runs > max_comparisons:
            df_is_same = False
            print('No unequal df found after {} runs'.format(count_runs))

    print('Delete the following folder if no longer needed: "{}"'.format(
            str(tmp_csv_folder)))


if __name__ == '__main__':
    main()

2 个答案:

答案 0 :(得分:0)

您的变体是由其他内容引起的,例如执行之间的输入数据更改或源代码更改。

浮点精度在执行之间不会产生不同的结果。

顺便说一句,清理你的例子,你会发现错误。此时你会说一些关于和int但是显示一个十进制值而不是!!

答案 1 :(得分:0)

将numexpr更新为2.4.6(或更高版本),因为numexpr 2.4.4在Windows上有一些错误。运行更新后,它适用于我。