5

我有一个 CSV 文件,其中的行如下所示:

ID,98.4,100M,55M,65M,75M,100M,75M,65M,100M,98M,100M,100M,92M,0#,0N#,

我可以用

#!/usr/bin/env python

import pandas as pd
import sys

filename = sys.argv[1]
df = pd.read_csv(filename)

给定一个特定的列,我想按 ID 拆分行,然后输出每个 ID 的平均值和标准差。

我的第一个问题是,如何从数字中删除所有非数字部分,例如“100M”和“0N#”,它们应该分别为 100 和 0。

我还尝试遍历相关标题并使用

df[header].replace(regex=True,inplace=True,to_replace=r'\D',value=r'')

正如Pandas DataFrame 中所建议的:从列中的字符串中删除不需要的部分

但是,这会将 98.4 更改为 984。

4

2 回答 2

3

使用str.extract

In [356]:
import io
import pandas as pd
t="""ID,98.4,100M,55M,65M,75M,100M,75M,65M,100M,98M,100M,100M,92M,0#,0N#"""
df = pd.read_csv(io.StringIO(t), header=None)
df

Out[356]:
   0     1     2    3    4    5     6    7    8     9    10    11    12   13  \
0  ID  98.4  100M  55M  65M  75M  100M  75M  65M  100M  98M  100M  100M  92M   

   14   15  
0  0#  0N#  

In [357]:
for col in df.columns[2:]:
    df[col] = df[col].str.extract(r'(\d+)').astype(int)
df

Out[357]:
   0     1    2   3   4   5    6   7   8    9   10   11   12  13  14  15
0  ID  98.4  100  55  65  75  100  75  65  100  98  100  100  92   0   0

如果您有浮点数,则可以使用以下正则表达式:

In [379]:
t="""ID,98.4,100.50M,55.234M,65M,75M,100M,75M,65M,100M,98M,100M,100M,92M,0#,0N#"""
df = pd.read_csv(io.StringIO(t), header=None)
df

Out[379]:
   0     1        2        3    4    5     6    7    8     9    10    11  \
0  ID  98.4  100.50M  55.234M  65M  75M  100M  75M  65M  100M  98M  100M   

     12   13  14   15  
0  100M  92M  0#  0N#  

In [380]:    
for col in df.columns[2:]:
    df[col] = df[col].str.extract(r'(\d+\.?\d+)').astype(np.float)
df

Out[380]:
   0     1      2       3   4   5    6   7   8    9   10   11   12  13  14  15
0  ID  98.4  100.5  55.234  65  75  100  75  65  100  98  100  100  92 NaN NaN

so(\d+\.?\d+)查找包含\d+1 个或多个数字(\.?可选小数点)和小数点\d+后 1 个或多个数字的组

编辑

OK 编辑了我的正则表达式模式:

In [408]:
t="""Name,97.7,0A,0A,65M,0A,100M,5M,75M,100M,90M,90M,99M,90M,0#,0N#"""
df = pd.read_csv(io.StringIO(t), header=None)
df

Out[408]:
     0     1   2   3    4   5     6   7    8     9    10   11   12   13  14  \
0  Name  97.7  0A  0A  65M  0A  100M  5M  75M  100M  90M  90M  99M  90M  0#   

    15  
0  0N#  

In [409]:    
for col in df.columns[2:]:
    df[col] = df[col].str.extract(r'(\d+\.*\d*)').astype(np.float)
df

Out[409]:
     0     1   2   3   4   5    6   7   8    9   10  11  12  13  14  15
0  Name  97.7   0   0  65   0  100   5  75  100  90  90  99  90   0   0
于 2015-11-13T10:26:16.263 回答
2

我的第一个问题是,如何从数字中删除所有非数字部分,例如“100M”和“0N#”,它们应该分别为 100 和 0。

import re
df = pd.read_csv(yourfile, header=None)
df.columns = ['ID'] + list(df.columns)[1:]
df = df.stack().apply(lambda v: re.sub('[^0-9]','', v) 
                 if isinstance(v, str) else v).astype(float).unstack()
df.groupby('ID').agg(['std', 'mean'])

这里.stack()将数据框转换为系列,.apply()为每个值调用 lambda,re.sub()删除任何非数字字符,.astype()转换为数字并将unstack()系列转换回数据框。这对于整数和浮点数同样适用。

给定一个特定的列,我想按 ID 拆分行,然后输出每个 ID 的平均值和标准差。

 # for all columns
 df.groupby('ID').agg(['std', 'mean'])
 # for specific column
 df.groupby('ID')['<colname>'].agg(['std', 'mean'])

输出数据框

以下是示例中使用的数据:

from StringIO import StringIO
s="""
1,98.4,100M,55M,65M,75M,100M,75M,65M,100M,98M,100M,100M,92M,0#,0N#,
1,98.4,100M,55M,65M,75M,100M,75M,65M,100M,98M,100M,100M,92M,0#,0N#,
2,98.4,100M,55M,65M,75M,100M,75M,65M,100M,98M,100M,100M,92M,0#,0N#,
2,98.4,100M,55M,65M,75M,100M,75M,65M,100M,98M,100M,100M,92M,0#,0N#,
"""
yourfile = StringIO(s)
于 2016-07-28T06:35:01.810 回答