背景 CSV 是一种以逗号进行特征分隔的文本文件类型,在数据库或电子表格中是一种非常常见的导入导出格式。本篇图文就以泰坦尼克号船员获救预测( Kaggle)中使用的数据集为例来说明 C#、Python和Pandas如何读取 CSV 数据的。
CSV原始文件如下图所示:
CSV原始文件 样本的特征如下:
Survival:是否生还(0 = No,1 = Yes) Pclass:船仓等级(1 = 1st,2 = 2nd,3 = 3rd) Sibsp:兄弟姐妹(siblings)/配偶(spouses)数量 Parch:父母(parents)/子女(children)数量 Embarked:登船港口(C = Cherbourg,Q = Queenstown,S = Southampton) 技术分析 C# 属于强类型语言,CSV 文件可以看作样本的集合,所以需要先定义样本的结构,之后再把每一个样本对象放入链表中形成集合。有了样本的集合我们就可以自己写代码或者使用 LINQ 技术来分析这些样本数据了。
Python 自带了 CSV 模块,通过 CSV 模块中的reader()
方法可以得到序列的迭代器,之后用 foreach 语句获取所有的样本数据。
Pandas 更加的方便,通过read_csv()
方法可以直接得到一个DataFrame
结构,基于该结构可以进行下一步的数据分析。
利用C#语言读取CSV数据 Step1:把样本特征封装到类中。
public class PassengerItem { public int PassengerId; public int Survived; public int Pclass; public string Name; public string Sex; public double Age; public int SibSp; public int Parch; public string Ticket; public double Fare; public string Cabin; public string Embarked; }
Step2:读取 CSV 获取样本的集合。
public static List<PassengerItem> GetData(string filePath) { List<PassengerItem> result = new List<PassengerItem>(); string [] strs = File.ReadAllLines(filePath); for (int i = 1 ; i < strs.Length; i++) { string str = strs[i]; if (string .IsNullOrEmpty(str)) continue ; PassengerItem pItem = new PassengerItem(); int start = str.IndexOf(",\"" , StringComparison.Ordinal); int end = str.IndexOf("\"," , StringComparison.Ordinal); pItem.Name = str.Substring(start + 2 , end - start - 2 ); str = str.Remove(start, end - start + 1 ); string [] s = str.Split(',' ); if (!int .TryParse(s[0 ].Trim(), out pItem.PassengerId)) { pItem.PassengerId = int .MaxValue; } if (!int .TryParse(s[1 ].Trim(), out pItem.Survived)) { pItem.Survived = int .MaxValue; } if (!int .TryParse(s[2 ].Trim(), out pItem.Pclass)) { pItem.Pclass = int .MaxValue; } pItem.Sex = s[3 ].Trim(); if (!double .TryParse(s[4 ].Trim(), out pItem.Age)) { pItem.Age = double .MaxValue; } if (!int .TryParse(s[5 ].Trim(), out pItem.SibSp)) { pItem.SibSp = int .MaxValue; } if (!int .TryParse(s[6 ].Trim(), out pItem.Parch)) { pItem.Parch = int .MaxValue; } pItem.Ticket = s[7 ].Trim(); if (!double .TryParse(s[8 ].Trim(), out pItem.Fare)) { pItem.Fare = double .MaxValue; } pItem.Cabin = s[9 ].Trim(); pItem.Embarked = s[10 ].Trim(); result.Add(pItem); } return result; }
Step3:利用 LINQ 来处理样本的数据。
static void Main (string [] args) { List<PassengerItem> p = GetData(@".\train.csv" ); int i = p.Count(a => !string .IsNullOrEmpty(a.Cabin)); int j = p.Count(a => !string .IsNullOrEmpty(a.Embarked)); Console.WriteLine("Cabin:" + i); //Cabin:204 Console.WriteLine("Embarked:" + j); //Embarked:889 }
利用Python读取CSV数据 使用 CSV 模块的reader()
方法,从下面的代码长度,我们可以看出读取 CSV 文件 Python 比 C# 要简单的多,但统计某一列信息还需要推导式来辅助完成。
import csvwith open('train.csv' ) as f: reader = csv.reader(f) head_row = next(reader) # 读取表头 rows = [row for row in reader] # 读取数据集 # 读取列 Cabin = [row[10 ] for row in rows if row[10 ].strip() is not '' ] Embarked = [row[11 ] for row in rows if row[11 ].strip() is not '' ] print("Cabin:{0}" .format(len(Cabin))) print("Embarked:{0}" .format(len(Embarked)))# Cabin:204 # Embarked:889
利用Pandas读取CSV数据 使用 Pandas 的read_csv()
方法可以很方便的读取 CSV 文件,之后可以通过行索引或列索引很方便的获取样本或特征数据。
import pandas as pd df = pd.read_csv(r'.\train.csv') print(df.info()) # <class 'pandas.core.frame.DataFrame'> # RangeIndex: 891 entries, 0 to 890 # Data columns (total 12 columns): # # Column Non-Null Count Dtype # --- ------ -------------- ----- # 0 PassengerId 891 non-null int64 # 1 Survived 891 non-null int64 # 2 Pclass 891 non-null int64 # 3 Name 891 non-null object # 4 Sex 891 non-null object # 5 Age 714 non-null float64 # 6 SibSp 891 non-null int64 # 7 Parch 891 non-null int64 # 8 Ticket 891 non-null object # 9 Fare 891 non-null float64 # 10 Cabin 204 non-null object # 11 Embarked 889 non-null object # dtypes: float64(2), int64(5), object(5) # memory usage: 83.7+ KB
总结 本文介绍了如何利用 C#、Python以及Pandas 来读取 CSV 文件,通过对比可以发现 Pandas 最为便捷。有一个感悟是需要与大家分享的,针对不同的场景,要换不同的语言来实现呀,千万不要向我当年那样所有的场景都用自己最熟悉的语言,比如自己写 SVM 的实现,而 sklearn 只需要配参数就好,结果耗费了不少时间精力,还没有人家写的好。哭死!!