【问题标题】:iteratively read (tsv) file for Pandas DataFramePandas DataFrame 的迭代读取 (tsv) 文件
【发布时间】:2013-06-17 10:56:29
【问题描述】:

我有一些看起来像这样的实验数据 - http://paste2.org/YzJL4e1b(太长,无法在此处发布)。由字段名称行分隔的块是同一实验的不同试验 - 我想读取 pandas 数据框中的所有内容,但将其组合在一起某些试验(例如 0、1、6、7 放在一起 - 和 2, 3,4,5 一起组成另一组)。这是因为不同的试验条件略有不同,我想分析这些条件之间的结果差异。我有一个来自另一个文件的不同条件的数字列表。

目前我正在这样做:

tracker_data = pd.DataFrame
tracker_data = tracker_data.from_csv(bhpath+i+'_wmet.tsv', sep='\t', header=4)
tracker_data['GazePointXLeft'] = tracker_data['GazePointXLeft'].astype(np.float64) 

但这当然只是一次性读取所有内容(包括字段名称行) - 如果我能以某种方式嵌套块,这让我可以通过数字索引轻松访问它们,那就太好了...

你有什么想法我能做到最好吗?

【问题讨论】:

  • 啊,我想我真的很接近了。 @TheCymera,您上传的数据在您的机器上是否准确无误?在缺少数据的情况下,如何处理第一行的最后几列?它们只是标签吗?
  • 是的,我从 Leafpad(我的文本基本编辑器)复制/粘贴了内容。最后几列并没有真正困扰我 - 这是我想做的选择性分箱。

标签: python pandas dataframe eye-tracking


【解决方案1】:

我最终以迭代方式进行。非常非常反复。似乎没有其他工作。

pat = 'TimeStamp    GazePointXLeft  GazePointYLeft  ValidityLeft    GazePointXRight GazePointYRight ValidityRight   GazePointX  GazePointY  Event'
with open(bhpath+fileid+'_wmet.tsv') as infile:
    eye_data = infile.read().split(pat)
    eye_data = [trial.split('\r\n') for trial in eye_data] # split at '\r'
    for idx, trial in enumerate(eye_data):
        trial = [row.split('\t') for row in trial]
        eye_data[idx] = trial

【讨论】:

    【解决方案2】:

    我还没有完全让它工作,但我认为这是因为我复制/粘贴数据的方式。试试这个,如果它不起作用,请告诉我。

    借鉴this question的一些灵感

    pat = "TimeStamp\tGazePointXLeft\tGazePointYLeft\tValidityLeft\tGazePointXRight\tGazePointYRight\tValidityRight\tGazePointX\tGazePointY\tEvent\n"
    with open('rec.txt') as infile:
        header, names, tail = infile.read().partition(pat)
    
    names = names.split()  # get rid of the tabs here
    all_data = tail.split(pat)
    res = [pd.read_csv(StringIO(x), sep='\t', names=names) for x in all_data]
    

    我们读入整个文件,因此这不适用于大文件,然后根据给出列名的已知行对其进行分区。 tail 只是一个包含其余数据的字符串,因此我们可以再次根据名称对其进行拆分。可能有比使用 StringIO 更好的方法,但这应该可行。

    我注意到您希望如何将单独的块连接在一起,但这会将它们保留为一个列表。您可以根据需要从那里连接。

    对于较大的文件,您可能需要编写一个生成器来读取,直到您点击列名并写入一个新文件,直到您再次点击它们。然后使用像安迪的答案这样的东西单独阅读这些内容。

    关于如何使用多个块的单独问题。假设你有Dataframes 的列表,我称之为res,你可以使用pandas 的concat 将它们连接到一个带有MultiIndex 的DataFrame 中(另请参阅Andy 发布的链接)。

    In [122]: df = pd.concat(res, axis=1, keys=['a', 'b', 'c'])  # Use whatever makes sense for the keys
    
    In [123]: df.xs('TimeStamp', level=1, axis=1)
    Out[123]: 
         a    b    c
    0  NaN  NaN  NaN
    1  0.0  0.0  0.0
    2  3.3  3.3  3.3
    3  6.6  6.6  6.6
    

    【讨论】:

    • 我尝试使用代码,但第三行似乎不起作用 - header, names, tail = infile.read().partition(pat) 将所有数据写入 header 而 names和尾巴是空的。
    • 玩拍拍。为确保您获得所需的内容,请尝试 f = open('rec.txt')pat = f.read() 4 或 5 次。 f.read() 将一次读取一行,因此您必须摆脱标题。将 pat 分配给正确的字符串后,再试一次。
    【解决方案3】:

    您应该使用read_csv 而不是from_csv*:

    tracker_data = pd.read_csv(bhpath+i+'_wmet.tsv', sep='\t', header=4)
    

    如果你想加入这样的 DataFrame 列表,你可以使用 concat:

    trackers = (pd.read_csv(bhpath+i+'_wmet.tsv', sep='\t', header=4) for i in range(?))
    df = pd.concat(trackers)
    

    * 我认为已弃用。

    【讨论】:

    • 我想你误解了我想要做什么 - 这些块都在一个文件中 - 不是我们的代码所暗示的不同文件。
    • @TheChymera 道歉,我看错了。我不太确定你在追求什么。您是否要求读取仅在某些列中读取的 csv?
    • 不,我要求一种方法来读取整个 .tsv 文件(没有分隔包含字符串的行),但是我可以通过索引调用由这些行分隔的块。可能有人认为像 3d 数据框?
    • @TheChymera 你正在寻找一个 MultiIndex ......明天将充实一个答案:)
    猜你喜欢
    • 2017-11-14
    • 2017-01-14
    • 2012-03-28
    • 2020-01-03
    • 2021-12-28
    • 1970-01-01
    • 2022-01-22
    • 2013-09-23
    • 2013-09-02
    相关资源
    最近更新 更多