Pandas按行读取数据

3

通常,数据的呈现方式是将列作为变量,但如果我有一个.txt文件,其中包含以下内容:

Data1,1,2,3,4,5
Data2,3,1,4

我能否使用pandas这样的方式,构建出与我想要获得的数据框相同的数据框呢?

d = {"Data1":[1,2,3,4,5], "Data2": [3,1,4,1,2]}
df = pd.DataFrame(data=d)

编辑: 最初我希望数据集的大小不同,但是pandas不允许这样做,并抛出了ValueError错误。


d = {"Data1":[[1,2,3,4,5]], "Data2": [[3,1,4]]} - BENY
4个回答

2

将文件读入,转置数据框,稍加处理... 就可以了。

为伪造文件进行设置:

>>> from io import StringIO
>>> file = StringIO('''Data1,1,2,3,4,5
...:Data2,3,1,4''')

创建数据框架:
>>> df = pd.read_csv(file, header=None).T
>>> df = df.rename(columns=df.loc[0]).drop(0, axis=0)
>>> 
>>> df
>>> 
  Data1 Data2
1     1     3
2     2     1
3     3     4
4     4   NaN
5     5   NaN

然而,Peter Leimbigler在这个答案中更加优雅地解决了这个问题!

正如ALollz所指出的那样,在文件中第一行的字段数大于其他行时,这些解决方案都不适用。

以下是我尝试提供的更普遍适用的解决方案:

>>> file = StringIO('''Data1,3,1,4
...:Data2,1,2,3,4,5
...:Data3,7,8''')
>>> df = pd.concat([pd.Series(line.split(',')) for line in file], axis=1)
>>> df.rename(columns=df.loc[0]).drop(0, axis=0).astype(float)
>>> 
   Data1  Data2  Data3
1    3.0    1.0    7.0
2    1.0    2.0    8.0
3    4.0    3.0    NaN
4    NaN    4.0    NaN
5    NaN    5.0    NaN

2
但这只能工作是因为第一行恰好有最多的数据。如果交换行,它就会失败,因为它无法正确地进行标记化。 - ALollz
1
@ALollz 是的,我尝试着寻找一个更通用的解决方案,而不是复制你的 ;) - timgeb

2

如果你的第一行不是最长的,你可以读取整行并使用pandas进行分割。

df = pd.read_csv('test.csv', sep='\n', header=None)
df[0].str.split(',', expand=True).set_index(0).rename_axis(None,0).T

  Data1 Data2 Data3
1     1     3     1
2     2     1     2
3     3     4     3
4     4  None     4
5     5  None     5
6  None  None     6
7  None  None     7
8  None  None     8
9  None  None     9

示例数据: test.csv:

Data1,1,2,3,4,5
Data2,3,1,4
Data3,1,2,3,4,5,6,7,8,9

诚实的问题 - 这是否真的是使用pandas导入CSV数据的最佳方法,其中第一行不是最长的? - Evan
1
@Evan 我不知道。解析器期望永远不会看到任何行比第一行非标题行的字段更多,所以我认为唯一安全的方法是使用pandas将所有内容读入单个字段中。我对实现这一点的其他方法感到困惑。可能有更聪明的方法来使用.csv阅读器,但这两行代码在概念上很简单。 - ALollz

2
df = pd.read_csv('example_data.txt', header=None, index_col=0).T
df
0  Data1  Data2
1    1.0    3.0
2    2.0    1.0
3    3.0    4.0
4    4.0    NaN
5    5.0    NaN

啊,太好了!编辑:@Alex 我认为应该在这里打勾! - timgeb
@timgeb,我看到我们在完全相同的时间得出了非常相似的答案 :) - Peter Leimbigler

0

您可以使用以下代码:data_dict = {line.split(',')[0]:{line.split(',')[1:] for line in lines},其中lines是读取数据创建的。然后应用任何规则以获取[3,1,4,1,2]而不是[3,1,4](您没有说明想要什么规则)。最后执行pd.DataFrame(data_dict)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接