Python 搜索系列中的值,并在该值处拆分系列

Python 搜索系列中的值,并在该值处拆分系列,python,csv,python-3.x,pandas,Python,Csv,Python 3.x,Pandas,Python 3.3.3 熊猫0.12.0 我有一个单列.csv文件,其中有数百个浮点值,由一个任意字符串分隔(该字符串包含字母edit:并将随运行而变化)。我是一名熊猫初学者,希望找到一种加载.csv文件的方法,并在该字符串级别将浮点值拆分为两列 我被困在第一部分(搜索字符串)中,以致于我还不能处理第二部分,我认为这应该容易得多 到目前为止,我一直在尝试使用raw=pandas.read_csv('myfile.csv',squeak=True),然后使用类似raw.str.findall('

Python 3.3.3 熊猫0.12.0

我有一个单列.csv文件,其中有数百个浮点值,由一个任意字符串分隔(该字符串包含字母edit:并将随运行而变化)。我是一名熊猫初学者,希望找到一种加载.csv文件的方法,并在该字符串级别将浮点值拆分为两列

我被困在第一部分(搜索字符串)中,以致于我还不能处理第二部分,我认为这应该容易得多

到目前为止,我一直在尝试使用
raw=pandas.read_csv('myfile.csv',squeak=True)
,然后使用类似
raw.str.findall('a-z'))
,但我运气不太好。如果有人能帮忙,我将不胜感激。我计划在许多类似的.csv文件上使用此过程,因此我希望找到一种相当自动化的方法来执行此任务

示例input.csv:

123.4932
239.348
912.098098989
49391.1093
....
This is a fake string that splits the data.
....
1323.4942
2445.34223
914432.4
495391.1093090
所需的最终数据帧:

Column A         Column B
123.4932         1323.4942
239.348          2445.34223
912.098098989    914432.4
49391.1093       495391.1093090
...              ...
如果你能给我指出正确的方向,再次感谢你


20131123 编辑:感谢您迄今为止的回复。更新以反映拆分字符串将不会保持不变,因此我声明我一直在尝试使用正则表达式
raw.str.findall('[a-z]')
而不是使用
。来找到解决方案

此时,我的解决方案是读取.csv文件并使用
re
进行拆分,累积到列表中,然后将其加载到pandas中

import pandas as pd
import re

raw = open('myfile.csv', 'r').read().split('\n')
df = pd.DataFrame()
keeper = []
counter = 0

# Iterate through the rows. Consecutive rows that can be made into float are accumulated.
for row in raw:
    try:
        keeper.append(float(row))
    except:
        if keeper:
            df = pd.concat([df, pd.DataFrame(keeper, columns = [counter] )], axis = 1)
            counter += 1            
        keeper = []

# Get the last column, assuming the file hasn't ended on a line
# that will trigger the exception in the above loop.
if keeper:
    df = pd.concat([df, pd.DataFrame(keeper, columns = [counter] )], axis = 1)

df.describe()
谢谢你的进一步建议

20180729 EDIT2:另一种可能的解决方案,使用:


如果您知道只有两列,那么您可以执行以下操作

>>> ser = pd.read_csv("colsplit.csv", header=None, squeeze=True)
>>> split_at = ser.str.contains("fake string that splits").idxmax()
>>> parts = [ser[:split_at], ser[split_at+1:]]
>>> parts = [part.reset_index(drop=True) for part in parts]
>>> df = pd.concat(parts, axis=1)
>>> df.columns = ["Column A", "Column B"]
>>> df
        Column A            Column B
0       123.4932                ....
1        239.348           1323.4942
2  912.098098989          2445.34223
3     49391.1093            914432.4
4           ....      495391.1093090
5            NaN  extra test element
如果您有任意数量的位置要拆分,那么您可以使用布尔级数/shift/cumsum/groupby模式,但是如果您可以不使用它,那就更好了

(注:我确信有一种比idxmax更好的方法,但就我的一生而言,我现在记不起这个成语来找到第一个正确的答案。
split_at[split_at].index[0]
可以做到,但我不确定这是否更好。)

使用
numpy.split()

输出:

               0               1                2
0       123.4932       1323.4942       31323.4942
1        239.348      2445.34223      42445.34223
2  912.098098989        914432.4        2914432.4
3     49391.1093  495391.1093090  5495391.1093090
4            NaN             NaN         23423432

实际上,分隔符是什么?不幸的是,read_csv的lineterminator arg不允许您这样做(但?
ValueError:只支持长度为1的行终止符
是的,不幸的是,pandas仍然无法处理非结构化的数据。在这种情况下,解决方案涉及文本编辑器或(更方便的)Unix命令行工具。这将是我的连续groupby的另一个使用案例,尽管没有它,我们可以轻松完成这一任务。实际的分隔符会有所不同,但始终是以几个单词开头的句子,可能是一些数字和符号。应始终使
.match('\d+')
失败。
import io
import numpy as np
import pandas as pd

txt = """123.4932
239.348
912.098098989
49391.1093
This is a fake string that splits the data.
1323.4942
2445.34223
914432.4
495391.1093090
fake again
31323.4942
42445.34223
2914432.4
5495391.1093090
23423432"""

s = pd.read_csv(io.BytesIO(txt), header=None, squeeze=True)
mask = s.str.contains("fake")
pos = np.where(mask)[0]
pos -= np.arange(len(pos))

arrs = [s.reset_index(drop=True) for s in np.split(s[~mask], pos)]
pd.concat(arrs, axis=1, ignore_index=True).astype(float)
               0               1                2
0       123.4932       1323.4942       31323.4942
1        239.348      2445.34223      42445.34223
2  912.098098989        914432.4        2914432.4
3     49391.1093  495391.1093090  5495391.1093090
4            NaN             NaN         23423432