dataset_datasets - CSDN
dataset 订阅
DataSet是ADO.NET的中心概念。可以把DataSet当成内存中的数据库,DataSet是不依赖于数据库的独立数据集合。所谓独立,就是说,即使断开数据链路,或者关闭数据库,DataSet依然是可用的,DataSet在内部是用XML来描述数据的,由于XML是一种与平台无关、与语言无关的数据描述语言,而且可以描述复杂关系的数据,比如父子关系的数据,所以DataSet实际上可以容纳具有复杂关系的数据,而且不再依赖于数据库链路。 展开全文
DataSet是ADO.NET的中心概念。可以把DataSet当成内存中的数据库,DataSet是不依赖于数据库的独立数据集合。所谓独立,就是说,即使断开数据链路,或者关闭数据库,DataSet依然是可用的,DataSet在内部是用XML来描述数据的,由于XML是一种与平台无关、与语言无关的数据描述语言,而且可以描述复杂关系的数据,比如父子关系的数据,所以DataSet实际上可以容纳具有复杂关系的数据,而且不再依赖于数据库链路。
信息
应用领域
数据库
概    述
DataSet是ADO.NET的中心概念
特    点
独立性、离线
优    势
处理脱机数据等
中文名
DataSet
实    质
DataTable物件集合
DataSet概述
DataSet 是 ADO. NET结构的主要组件,它是从数据源中检索到的数据在内存中的缓存。DataSet 由一组 DataTable 对象组成,可使这些对象与 DataRelation 对象互相关联。还可通过使用 UniqueConstraint 和 ForeignKeyConstraint 对象在 DataSet 中实施数据完整性。 [1]  正是由于DataSet才使得程序员在编程时可以屏蔽数据库之间的差异,从而获得一致的编程模型。DataSet支持多表、表间关系、数据约束等,和关系数据库的模型基本一致。ado.net DataSet 的设计已明确指出它可独立于任何资料来源外而存取资料。因此,它可与多个不同的资料里来源搭配使用、与 XML 资料搭配使用,或用于管理应用程序的本机资料。DataSet 包含一或多个由资料列和资料行所组成的DataTable物件集合,以及 DataTable 物件中的主索引键、外部索引键、条件约束 (Constraint) 及资料的相关资讯。尽管 DataTable 对象中包含数据,但是 DataRelationCollection 允许遍览表的层次结构。这些表包含在通过 Tables 属性访问的 DataTableCollection 中。当访问 DataTable 对象时,请注意它们是按条件区分大小写的。例如,如果一个 DataTable 被命名为“mydatatable”,另一个被命名为“Mydatatable”,则用于搜索其中一个表的字符串被认为是区分大小写的。但是,如果“mydatatable”存在而“Mydatatable”不存在,则认为该搜索字符串不区分大小写。 [1]  DataSet 可将数据和架构作为 XML 文档进行读写。数据和架构可通过 HTTP 传输,并在支持 XML 的任何平台上被任何应用程序使用。可使用 WriteXmlSchema 方法将架构保存为 XML 架构,并且可以使用 WriteXml 方法保存架构和数据。若要读取既包含架构也包含数据的 XML 文档,可使用 ReadXml 方法。在典型的多层实现中,用于创建和刷新 DataSet 并依次更新原始数据的步骤包括:通过 DataAdapter 使用数据源中的数据生成和填充 DataSet 中的每个 DataTable。通过添加、更新或删除 DataRow 对象更改单个 DataTable 对象中的数据。调用 GetChanges 方法以创建只反映对数据进行的更改的第二个 DataSet。调用 DataAdapter 的 Update 方法,并将第二个 DataSet 作为参数传递。调用 Merge 方法将第二个 DataSet 中的更改合并到第一个中。针对 DataSet 调用 AcceptChanges。或者,调用 RejectChanges 以取消更改。需要注意的是:dataset所有数据都加载在内存上执行的,可以提高数据访问速度,提高硬盘数据的安全性。极大的改善了程序运行的速度和稳定性。 [1] 
收起全文
精华内容
参与话题
  • DataSet是什么,怎么用

    千次阅读 2019-07-16 19:26:45
    什么是DataSetDataSet是分布式的数据集合。DataSet是在Spark1.6中添加的新的接口。它集中了RDD的优点(强类型和可以用强大lambda函数)以及Spark SQL优化的执行引擎。DataSet可以通过JVM的对象进行构建,可以用...

    什么是DataSet?
    DataSet是分布式的数据集合。DataSet是在Spark1.6中添加的新的接口。它集中了RDD的优点(强类型和可以用强大lambda函数)以及Spark SQL优化的执行引擎。DataSet可以通过JVM的对象进行构建,可以用函数式的转换(map/flatmap/filter)进行多种操作。

    DataFrame、DataSet、RDD的区别

    假设RDD中的两行数据长这样:
    在这里插入图片描述
    那么DataFrame中的数据长这样:

    那么Dataset中的数据长这样: 在这里插入图片描述
    或者长这样(每行数据是个Object):
    在这里插入图片描述

    DataSet包含了DataFrame的功能,Spark2.0中两者统一,DataFrame表示为DataSet[Row],即DataSet的子集。
    (1)DataSet可以在编译时检查类型
    (2)并且是面向对象的编程接口
    相比DataFrame,Dataset提供了编译时类型检查,对于分布式程序来讲,提交一次作业太费劲了(要编译、打包、上传、运行),到提交到集群运行时才发现错误,这会浪费大量的时间,这也是引入Dataset的一个重要原因。

    DataFrame与DataSet的互转
    DataFrame和DataSet可以相互转化。
    (1)DataFrame转为 DataSet
    df.as[ElementType]这样可以把DataFrame转化为DataSet。
    (2)DataSet转为DataFrame
    ds.toDF()这样可以把DataSet转化为DataFrame。

    创建DataSet

    (1)通过spark.createDataset创建

    //todo:1、创建SparkSession,指定appName和master
    val spark: SparkSession = SparkSession.builder()
      .appName("SparkSqlSchema")
      .master("local[2]")
      .getOrCreate()
    //需要导入隐式装换
    import spark.implicits._
    //创建dataframe的方式1
    val ds: Dataset[Int] = spark.createDataset(0 to 10)
    ds.show()
    spark.stop()
    

    (2)通toDS方法生成DataSet

    //todo:1、创建SparkSession,指定appName和master
    val spark: SparkSession = SparkSession.builder()
      .appName("SparkSqlSchema")
      .master("local[2]")
      .getOrCreate()
    //需要导入隐式装换
    import spark.implicits._
    val df = spark.createDataFrame(List(Person01("Jason", 34), Person01("Tom", 20)))
    val ds: Dataset[Person01] = df.as[Person01]
    ds.show()
    spark.stop()
    

    (3)通过List封装数据直接转换成dataSet

    //todo:1、创建SparkSession,指定appName和master
    val spark: SparkSession = SparkSession.builder()
      .appName("SparkSqlSchema")
      .master("local[2]")
      .getOrCreate()
    import spark.implicits._
    //需要导入隐式装换
    val ds = List(Person("Jason", 34), Person("Tom", 20)).toDS()
    ds.show();
    
    展开全文
  • DataSet用法详细

    万次阅读 2018-08-23 08:49:45
    DataSet用法详细 一、特点介绍 1、处理脱机数据,在多层应用程序中很有用。 2、可以在任何时候查看DataSet中任意行的内容,允许修改查询结果的方法。 3、处理分级数据 4、缓存更改 5、XML的完整性:DataSet...

    DataSet用法详细

    一、特点介绍

    1、处理脱机数据,在多层应用程序中很有用。

    2、可以在任何时候查看DataSet中任意行的内容,允许修改查询结果的方法。

    3、处理分级数据

    4、缓存更改

    5、XML的完整性:DataSet对象和XML文档几乎是可互换的。

    二、使用介绍

    1、创建DataSet对象:

    DataSetds = new DataSet("DataSetName");

    2、查看调用SqlDataAdapter.Fill创建的结构

    da.Fill(ds,"Orders");

    DataTabletbl = ds.Table[0];

    foreach(DataColumncol in tbl.Columns)

    Console.WriteLine(col.ColumnName);

    3、查看SqlDataAdapter返回的数据

    ①DataRow对象

    DataTabletbl = ds.Table[0];

    DataRowrow = tbl.Row[0];

    Console.WriteLine(ros["OrderID"]);

    ②检查存储在DataRow中的数据

    DataTabletbl = row.Table;

    foreach(DataColumncol in tbl.Columns)

    Console.WriteLine(row[col]);

    ③检查DatTable中的DataRow对象

    foreach(DataRowrow in tbl.Rows)

    DisplayRow(row);

    4、校验DataSet中的数据

    ①校验DataColumn的属性:ReadOnly,AllowDBNull,MaxLength,Unique

    ②DataTable对象的Constrains集合:UiqueConstraints,Primarykey,ForeignkeyConstraints

    通常不必刻意去创建ForeignkeyConstraints,因为当在DataSet的两个DataTable对象之间创建关系时会创建一个。

    ③用SqlDataAdapter.Fill模式来检索模式信息

    5、编写代码创建DataTable对象

    ①创建DataTable对象:

    DataTabletbl = new DataTable("TableName");

    ②将DataTable添加到DataSet对象的Table集合

    DataSetds = new DataSet();

    DataTabletbl = new DataTable("Customers");

    ds.Tables.Add(tbl);

    DataSetds = new DataSet();

    DataTabletbl = ds.Tables.Add("Customers");

    DataTable对象只能存在于至多一个DataSet对象中。如果希望将DataTable添加到多个DataSet中,就必须使用Copy方 法或Clone方法。Copy方法创建一个与原DataTable结构相同并且包含相同行的新DataTable;Clone方法创建一个与原 DataTable结构相同,但没有包含任何行的新DataTable。

    ③为DataTable添加列

    DataTabletbl = ds.Tables.Add("Orders");

    DataColumncol =tbl.Columns.Add("OrderID",typeof(int));

    col.AllowDBNull= false;

    col.MaxLength= 5;

    col.Unique= true;

    tbl.PrimaryKey= new DataColumn[]{tbl.Columns["CustomersID"]};

    当设置主键时,AllowDBNull自动设置为False;

    ④处理自动增量列

    DataSetds = new DataSet();

    DataTabletbl = ds.Tables.Add("Orders");

    DataColumncol = tbl.Columns.Add("OrderID",typeof(int));

    col.AutoIncrement= true;

    col.AutoIncrementSeed= -1;

    col.AutoIncrementStep= -1;

    col.ReadOnly= true;

    ⑤添加基于表达式的列

    tbl.Columns.Add("ItemTotal",typeof(Decimal),"Quantity*UnitPrice");

    6、修改DataTable内容

    ①添加新DataRow

    DataRowrow = ds.Tables["Customers"].NewRow();

    row["CustomerID"]= "ALFKI";

    ds.Tables["Customers"].Rows.Add(row);

    object[]aValues={"ALFKI","Alfreds","Anders","030-22222"};

    da.Tables["Customers"].LoadDataRow(aValues,false);

    ②修改当前行

    修改行的内容逼供内不会自动修改数据库中相应的内容,对行所做的修改被视为是随后将使用SqlDataAdapter对象来提交交给数据库的待定的更改。

    DataRowrowCustomer;

    rowCustomer= ds.Tables["Custoemrs"].Rows.Find("ANTON");

    if(rowCustomer== null)

        //没有查找客户

    else

    {

        rowCustomer["CompanyName"]="NewCompanyName";

        rowCustomer["ContactName"]="NewContactName";

    }

     

    //推荐使用这种方式

    DataRowrowCustomer;

    rowCustomer= ds.Tables["Custoemrs"].Rows.Find("ANTON");

    if(rowCustomer== null)

        //没有查找客户

    else

    {

        rowCustomer.BeginEdit();

        rowCustomer["CompanyName"]="NewCompanyName";

        rowCustomer["ContactName"]="NewContactName";

        rowCustomer.EndEdit();

    }

    //null表示不修改该列的数据

    obejct[]aCustomer ={null,"NewCompanyName","NewContactName",null}

    DataRowrowCustomer;

    rowCustomer= ds.Tables["Customers"].Rows.Find("ALFKI");

    rowCustomer.ItemArray= aCustomer;

    ③处理DataRow的空值

    //查看是否为空

    DataRowrowCustomer;

    rowCustomer= ds.Tables["Customers"].Rows.Find("ALFKI");

    if(rowCustomer.IsNull("Phone"))

    Console.WriteLine("It''''sNull");

    else

    Console.WriteLine("It''''snot Null");

     

    //赋予空值

    rowCustomer["Phone"]= DBNull.Value;

    ④删除DataRow

    DataRowrowCustomer;

    rowCustomer= ds.Tables["Customers"].Rows.Find("ALFKI");

    rowCustomer.Delete();

    ⑤清除DataRow

    DataRowrowCustomer = ds.Tables["Customers"].Rows.Find("ALFKI");

    rowCustomer.ItemArray= aCustomer;

    da.Tables["Customers"].Remove(rowCustomer);

    或者

    ds.Tables["Customers"].RemoveAt(intIndex);

    ⑥使用DataRow.RowState属性 :Unchanged,Detached,Added,Modified,Deleted

    privatevoid DemonstrateRowState()

    {

        // Run a function to create a DataTablewith one column.

        DataTable myTable = MakeTable();

        DataRow myRow;

        // Create a new DataRow.

        myRow = myTable.NewRow();

        // Detached row.

        Console.WriteLine("New Row " +myRow.RowState);

        myTable.Rows.Add(myRow);

        // New row.

        Console.WriteLine("AddRow " +myRow.RowState);

        myTable.AcceptChanges();

        // Unchanged row.

        Console.WriteLine("AcceptChanges" + myRow.RowState);

        myRow["FirstName"] ="Scott";

        // Modified row.

        Console.WriteLine("Modified " +myRow.RowState);

        myRow.Delete();

        // Deleted row.

        Console.WriteLine("Deleted " +myRow.RowState);

    }

    ⑦检查DataRow中的挂起更改

    DataRowrowCustomer;

    rowCustomer= ds.Tables["Customers"].Rows.Find("ALFKI");

    rowCustomer["CompanyName"]= "NewCompanyName";

    stringstrNewCompanyName,strOldCompanyName;

    Console.WriteLine(rowCustomer["CompanyName",DataRowVersion.Current]);

    Console.WriteLine(rowCustomer["CompanyName",DataRowVersion.Original]);

    ⑧遍历DataSet

    foreach(DataTabledt in dataSet.Tables)

    foreach(DataRowdr in dt.Rows)

    foreach(DataColumndc in dr.Table.Columns)

    Console.WriteLine(dr[dc]);

    三、属性方法事件介绍

    1、DataSet

    ①属性

    CaseSensitive:用于控制DataTable中的字符串比较是否区分大小写。

    DataSetName:当前DataSet的名称。如果不指定,则该属性值设置为"NewDataSet"。如果将DataSet内容写入XML文件,DataSetName是XML文件的根节点名称。

    DesignMode:如果在设计时使用组件中的DataSet,DesignMode返回True,否则返回False。

    HasErrors:表示DataSet中 的DataRow对象是否包含错误。如果将一批更改提交给数据库并将DataAdapter对象的ContinueUpdateOnError属性设置为 True,则在提交更改后必须检查DataSet的HasErrors属性,以确定是否有更新失败。

    NameSpace和Prefix:指定XML命名空间和前缀

    Relations:返回一个DataRelationCollection对象。

    Tables:检查现有的DataTable对象。通过索引访问DataTable有更好的性能。

    ②方法

    AcceptChanges和RejectChanges: 接受或放弃DataSet中所有挂起更改。调用AcceptChanges时,RowState属性值为Added或Modified的所有行的 RowState属性都将被设置为UnChanged.任何标记为Deleted的DataRow对象将从DataSet中删除。调用 RejectChanges时,任何标记为Added的DataRow对象将会被从DataSet中删除,其他修改过的DatRow对象将返回前一状态。

    Clear:清除DataSet中所有DataRow对象。该方法比释放一个DataSet然后再创建一个相同结构的新DataSet要快。

    Clone和Copy:使用Copy方法会创建与原DataSet具有相同结构和相同行的新DataSet。使用Clone方法会创建具有相同结构的新DataSet,但不包含任何行。

    GetChanges:返回与原DataSet对象具有相同结构的新DataSet,并且还包含原DataSet中所有挂起更改的行。

    GetXml和GetXmlSchema:使用GetXml方法得到由DataSet的内容与她的架构信息转换为XML格式后的字符串。如果只希望返回架构信息,可以使用GetXmlSchema。

    HasChange:表示DataSet中是否包含挂起更改的DataRow对象。

    Merge:从另一个DataSet、DataTable或现有DataSet中的一组DataRow对象载入数据。

    ReadXml和WriteXml:使用ReadXml方法从文件、TextReader、数据流或者XmlReader中将XML数据载入DataSet中。

    Reset:将DataSet返回为未初始化状态。如果想放弃现有DataSet并且开始处理新的DataSet,使用Reset方法比创建一个DataSet的新实例好。

    ③事件

    MergeFailed:在DataSet的Merge方法发生一个异常时触发。

    2、DataTable

    ①属性

    ②方法

    ③事件

    ColumnChanged:在列的内容被改变之后触发

    ColumnChangding:在列的内容被改变之前触发

    RowChanged,RowChanging,RowDeleted,RowDeleting

    3、DataColumn

    ①属性

    4、DataRow

    ①属性

    HasError:确定行是否包含错误。

    Item:通过指定行的列数,列的名称或DataColumn对象本身,访问列的内容。

    ItemArray:获取或设置行中所有列的值。

    RowError:返回一个包含行错误信息的字符串。

    RowState:返回DataRowState枚举中的值来表示行的当前状态。

    Table:返回DataRow对象所在的DataTable。

    ②方法

    AcceptChanges和RejectChanges:提交和放弃挂起更改。

    BeginEdit、CancelEdit、EndEdit

    ClearErrors:清除DataRow中所有的错误。

    Delete:Delete方法实际上并不从DataRow表的Row集合中删除该DataRow。当调用DataRow对象的Delete方法时,ADO.NET将该行标记为删除,之后调用SqlDataAdapter对象的Update方法来删除其在数据库中对应的行。

    如果希望彻底删除DataRow,可以调用Delete方法,接着再调用它的AccepteChanges方法,还可以使用DataRowCollection对象的Remove方法完成相同的任务。

    datasetds =new datast();

    datatabletel =new datatable();

    ds..tables.add(tel);

    stringcode=ds.tables["tel"].rows[0][0].tostring();

     

     

    浅谈DataSet 的用法

    DataSet 是ADO.NET开发人员为方便数据处理开发出来的,是数据的集合,是为解决DataReader的缺陷设计的,DataReader数据处理速度快,但 它是只读的,而且一旦移到下一行,就不能查看上一行的数据,DataSet则可以自由移动指针。DataSet的数据是与数据库断开的。DataSet 还可用于多层应用程序中,如果应用程序运行在中间层的业务对象中来访问数据库,则业务对象需将脱机数据结构传递给客户应用程序。

    DataSet的功能:浏览、排序、搜索、过滤、处理分级数据、缓存更改等。还可以与XML数据互换。DataSet中可包括多个 DataTable,可将多个查询结构存到一个DataSet中,方便操作,而DataTable中又包括多个DataRow、DataColumn,可 通过这些 DataRow、DataColumn来查看、操作其中的数据,而需将操作结果返回给数据库的话,则可以调用DataAdapter的Update方法。

    DataSet的操作:

    DataSetds=new DataSet();

    DataTabledt=new DataTable("newTable");

    ds.Tables.Add(dt);

    DataSetds=new DataSet();

    DataTabledt=ds.Tables.Add("newTable");

    上述两种方法都可以在DataSet中添加一个DataTable,看需要而进行选择。添加DataTable后,需向其中添加行和列。

    DataSetds=new DataSet();

    DataTabledt=ds.Tables.Add("newTables");

    DataColumncol=dt.Columns.Add("newColumn",typeof(int));

    col.AllowDBNull=false;

    col.MaxLength=4;

    col.Unique=true;

    上述代码向DataSet中的DataTable中添加名为”newColumn”,类型为int且不为空,最大长度为4和唯一性为真的列。

    dt.PrimaryKey=newDataColumn[]{dt.Columns["ID"]}

    这段代码是继续上面代码的,为一个DataTable中添加一个主键列,主键列是一个数据组,如有多个主键,只需在数组中添加一个列即可。如下:

    dt.PrimaryKey=newDataColumns[]{dt.Columns["OrderID"],dt.Columns["ProductID"]}

    添加外键:

    ForeignKeyConstraintfk;

    fk=newForeignKeyConstraint(ds.Tables["Customers"].Columns["CustomerID"],ds.Tables["Orders"].Columns["CustomerID"]);

    ds.Tables["Orders"].Constraints.Add(fk);

    上述代码假如已经为Cusomers表和Orders创建了主键,此句为添加外键约束。

    上述是根据Customers表和Orders表的CustomerID来创建约束。

    下面介绍修改DataRow中的内容:

    DataRowdr=ds.Tables["Customer"].Rows.Find("ANTON");

    if(dr==null)

    else

    {

        dr.BeginEdit();

        dr["CompanyName"]="newValue";

        dr["ContactName"]="newValue2";

        dr.EndEdit();

    }

    上面代码通过Row集合的Find方法来在DataTable中的行进行定位,找到"ANTON"行,再修改"ANTON"行中 CompanyName列和ContactName列的值。通过BeginEdit和EndEdit来缓存对行的修改,还可调用 CancelEdit为取消修改。

    判断某列是否为空值:

    DataRowdr=ds.Tables["Customers"].Rows.Find("aaa");

    if(dr.IsNull("ContactName");

        ..

    else

        dr["ContactName"]=DBNull.Value

    这里判断ContactName列是否为空,如果不是则为其赋空值,呵,很无厘头的做法,这里只为演示为列赋空值的做法。

    删除DataRow:

    有两种方法可以删除DataRow,Delete方法和Remove方法和RemoveAt方法。其区别是Delete方法实际上不是从 DataTable 中删除掉一行,而是将其标志为删除,仅仅是做个记号,而Remove方法则是真正的从DataRow中删除一行,RemoveAt方法是根本行的索引来删 除。列:

    DataRowdr=ds.Tables["table"].Rows.Find("a");

    ds.Tables["table"].Remove(dr);

    ds.Tables["table"].Remove(index);

    dr 为"a"所在的行,查出后将其删除,index为 "a"所在的索引号。关于DataSet中的其用法,参照MSDN

    DataRowdr=ds.Tables["Customers"].Rows.Find("aaa");

    if(dr.IsNull("ContactName");

        ..

    else

        dr["ContactName"]=DBNull.Value

    这里判断ContactName列是否为空,如果不是则为其赋空值,呵,很无厘头的做法,这里只为演示为列赋空值的做法。

    usingSystem.Data;

    usingSystem;

    usingSystem.Windows.Forms;

    classDataT

    {

        static DataTable dt;// = new DataTable();

        static DataSet ds;

        static void method1()

        {

            dt = new DataTable("Name");

            ds = new DataSet();

            dt.Columns.Add(newDataColumn("ID", typeof(Int32)));

            dt.Columns.Add(newDataColumn("Name", typeof(string)));

            dt.Columns.Add(newDataColumn("Sex", typeof(string)));

            dt.Columns.Add(newDataColumn("Addr", typeof(string)));

        }

        static void add(int id,string name,stringsex,string addr)

        {

            DataRow dr = dt.NewRow();

            dr["id"] = id;

            dr["Name"] = name;

            dr["Sex"] = sex;

            dr["Addr"] = addr;

            dt.Rows.Add(dr);

        }

        static void Main()

        {

            DataT DT = new DataT();

            method1();

            add(100,"Join","Male","北京");

            add(101,"Lily","feMale","北京");

            add(102,"JIM","Male","北京");

            ds.Tables.Add(dt);

            foreach(DataRow dr in dt.Rows)

            {

                MessageBox.Show(dr["ID"].ToString()+ " " + dr["Name"].ToString() + " " +dr["Sex"].ToString() + " " +dr["Addr"].ToString(),"Message");

                Console.WriteLine(dr["ID"].ToString()+ " " + dr["Name"].ToString()+ " " +dr["Sex"].ToString() + " " +dr["Addr"].ToString());

            }

            Try

            {

                foreach(DataTable dt2 in ds.Tables)

                foreach(DataRow dr in dt2.Rows)

                Console.WriteLine(dr["ID"].ToString()+ " " + dr["Name"].ToString() + " " + dr["Sex"].ToString()+ " " + dr["Addr"].ToString());

            }

            catch(Exception ex)

            {

                Console.WriteLine("dkfjksdjfk");

            }

        }

    }

    展开全文
  • C#中DataSet的用法(很详细)

    热门讨论 2020-07-30 23:32:51
    DataSet是ADO.NET开发人员为方便数据处理开发出来的,是数据的集合。DataSet的功能:浏览、排序、搜索、过滤、处理分级数据、缓存更改等。还可以与XML数据互换。DataSet中可包括多个DataTable,可将多个查询结构...
  • Dataset的用法简析

    万次阅读 2018-02-25 14:40:38
    之前的文章,稍微讲了一下Estimator的用法,也提到Estimator的数据处理使用的是tf.data这两个模块是Tensorflow初学者必须掌握的内容。现在,就让我们从大的概念入手,来慢慢理解tf.data的用法 ...

    之前的文章,稍微讲了一下Estimator的用法,也提到Estimator的数据处理使用的是tf.data这两个模块是Tensorflow初学者必须掌握的内容。现在,就让我们从大的概念入手,来慢慢理解tf.data的用法

    转载请注明出处

    推荐官方文档:https://tensorflow.google.cn/programmers_guide/datasets

    tf.data的作用

    在机器学习过程中,对数据的获取、过滤、使用、存储是很重要的一个内容,因为数据可能是不完整的、有杂质的、来源不同的。面对海量数据,我们当然不可能每次都手动整合。Tensorflow框架下,对数据的处理使用的是tf.data,它可以帮助我们以多种方式获取数据、灵活的处理数据和保存数据,使我们能够把更多的精力专注在算法的逻辑上。下面就让我们一起来学习。

    tf.data获取数据的方式

    这里着着重理解Dataset的概念
    Dataset是存储Tensor结构的类,它可以保存一批Tensor结构,以供模型来训练或者测试。这里,Tensor结构是自己定义的,可以有多种格式。
    Dataset获取数据的方式有多种,可以从Tensor获取,也可以从另一个Dataset转换而来,我们暂时只讲从Tensor获取。
    用到的接口为:

    tf.data.Dataset.from_tensor_slices()

    这个接口允许我们传递一个或多个Tensor结构给Dataset,因为默认把Tensor的第一个维度作为数据数目的标识,所以要保持数据结构中第一维的一致性,用代码说明一下:

    dataset = tf.data.Dataset.from_tensor_slices(
       {"a": tf.random_uniform([4]),
        "b": tf.random_uniform([4, 100], maxval=100, dtype=tf.int32)})
    print(dataset.output_types)  # ==> "{'a': tf.float32, 'b': tf.int32}"
    print(dataset.output_shapes)  # ==> "{'a': (), 'b': (100,)}"

    这里包含如下信息:
    1、该接口可以接受一个字典变量。实际上,该接口接受任何Iterator
    2、第一个维度被认为是数据的数量,可以看到,观察数据的shapes的时候,只显示第一维以后的,为什么呢,因为第一维被认为是数据的数量,所以不参与构成shapes

    Dataset输出数据的方式

    make_one_shot_iterator迭代器

    有进就有出,那么数据怎么从Dataset出来呢,代码如下:

    dataset = tf.data.Dataset.from_tensor_slices(np.random.randn(10,3))
    iterator = dataset.make_one_shot_iterator()
    next_element = iterator.get_next()
    
    with tf.Session() as sess:
        for i in range(10):
            value = sess.run(next_element)
            print(i, value)
    
    output:
    0 [ 0.78891609  0.31016679 -2.22261044]
    1 [ 3.06918115  0.14014906  0.86654045]
    2 [ 2.08348332  0.57866576 -0.66946627]
    3 [-1.28344434  1.96287407  0.70896466]
    4 [-1.28056116 -0.65352575  0.39975416]
    5 [-0.70007014 -0.94034185  1.02308444]
    6 [ 0.70819506 -0.56918389  0.75509558]
    7 [ 0.26925763 -0.18980865 -0.90350774]
    8 [ 1.45644465 -1.13308881 -0.37863782]
    9 [ 0.4485246  -0.48737583 -0.40142893]

    这里,我们先用numpy生成随机数据并储存在Dataset,之后,是用了dataset.make_one_shot_iterator()迭代器来读取数据。one_shot迭代器人如其名,意思就是数据输出一次后就丢弃了。
    这就构成了数据进出的一种方式,下面,我们多了解几种数据输出的迭代器

    make_initializable_iterator 迭代器

    可初始化迭代器允许Dataset中存在占位符,这样可以在数据需要输出的时候,再进行feed操作。实验代码如下:

    max_value = tf.placeholder(tf.int64, shape=[])
    dataset = tf.data.Dataset.range(max_value)
    iterator = dataset.make_initializable_iterator()
    next_element = iterator.get_next()
    
    with tf.Session() as sess:
    # Initialize an iterator over a dataset with 10 elements.
        sess.run(iterator.initializer, feed_dict={max_value: 10})#需要取数据的时候才将需要的参数feed进去
        for i in range(10):
          value = sess.run(next_element)
          assert i == value
    
        # Initialize the same iterator over a dataset with 100 elements.
        sess.run(iterator.initializer, feed_dict={max_value: 100})#feed了不同的参数
        for i in range(100):
          value = sess.run(next_element)
          assert i == value

    reinitializable 迭代器

    这个迭代器构造方式是根据数据的shapes和type,所以只要shapes和type相同,就可以接受不同的数据源来进行初始化,且可以反复初始化,见以下代码:

    # Define training and validation datasets with the same structure.
    training_dataset = tf.data.Dataset.range(100).map(
        lambda x: x + tf.random_uniform([], -10, 10, tf.int64))
    validation_dataset = tf.data.Dataset.range(50)
    
    # A reinitializable iterator is defined by its structure. We could use the
    # `output_types` and `output_shapes` properties of either `training_dataset`
    # or `validation_dataset` here, because they are compatible.
    iterator = tf.data.Iterator.from_structure(training_dataset.output_types,
                                               training_dataset.output_shapes)
    next_element = iterator.get_next()
    
    training_init_op = iterator.make_initializer(training_dataset)
    validation_init_op = iterator.make_initializer(validation_dataset)
    
    with tf.Session() as sess:
        # Run 20 epochs in which the training dataset is traversed, followed by the
        # validation dataset.
        for _ in range(20):#可以重复初始化
          # Initialize an iterator over the training dataset.
          sess.run(training_init_op)#每次初始化的数据可以不同
          for _ in range(100):
            sess.run(next_element)
    
          # Initialize an iterator over the validation dataset.
          sess.run(validation_init_op)#初始化了另一组数据
          for _ in range(50):
            sess.run(next_element)

    Iterator.from_string_handle 迭代器

    可以看到,reinitializable 已经具有较强的灵活性了,但是它还是每次加载数据都需要重新初始化,有没有可能省掉这一步呢,是可以的,Iterator.from_string_handle通过feed初始化句柄的方式,取得了更高的灵活性,代码如下

    # Define training and validation datasets with the same structure.
    training_dataset = tf.data.Dataset.range(100).map(
        lambda x: x + tf.random_uniform([], -10, 10, tf.int64)).repeat()
    validation_dataset = tf.data.Dataset.range(50)
    
    # A feedable iterator is defined by a handle placeholder and its structure. We
    # could use the `output_types` and `output_shapes` properties of either
    # `training_dataset` or `validation_dataset` here, because they have
    # identical structure.
    handle = tf.placeholder(tf.string, shape=[])
    iterator = tf.data.Iterator.from_string_handle(
        handle, training_dataset.output_types, training_dataset.output_shapes)
    next_element = iterator.get_next()
    
    # You can use feedable iterators with a variety of different kinds of iterator
    # (such as one-shot and initializable iterators).
    training_iterator = training_dataset.make_one_shot_iterator()
    validation_iterator = validation_dataset.make_initializable_iterator()
    
    # The `Iterator.string_handle()` method returns a tensor that can be evaluated
    # and used to feed the `handle` placeholder.
    training_handle = sess.run(training_iterator.string_handle())
    validation_handle = sess.run(validation_iterator.string_handle())
    
    # Loop forever, alternating between training and validation.
    while True:
      # Run 200 steps using the training dataset. Note that the training dataset is
      # infinite, and we resume from where we left off in the previous `while` loop
      # iteration.
      for _ in range(200):
        sess.run(next_element, feed_dict={handle: training_handle})
    
      # Run one pass over the validation dataset.
      sess.run(validation_iterator.initializer)
      for _ in range(50):
        sess.run(next_element, feed_dict={handle: validation_handle})

    从Dataset初始化Dataset

    讲完了如何读取数据,我们再回过头来讲获取数据的另一种方法:从Dataset获取。
    之所以这么安排,是因为要结合输出才能理解这种获取方法的意义。
    为了从dataset中初始化,这里有三个接口:

    Dataset.map
    Dataset.flat_map
    Dataset.filter

    这三个接口从字面上就很好理解,map就是对于给定Dataset中的每一个元素,都执行一次map操作,而flat_map就是既执行了map,还对数据进行了一次扁平化,也就是降维,而filter就是进行了一次过滤, 我们直接从代码的角度看以看这三个接口怎么用。

    代码虽然很大一段,需要理解的东西却很少, 首先,我们定义了一个3*2*3的随机多维数组,可以看到
    正常的输出就是输出3个2*3的数组
    而map的作用我这里写的是各数加一,所以输出的是3个2*3的各数加一的数组
    flat_map的作用是降维,所以输出的是6个1*3的数组
    filter的作用是过滤,所以输出的是我的过滤内容:[0][0]元素大于0.8的,由于最有一个数组其元素为0.76103773,被过滤掉了

    with tf.Session() as sess:
        np.random.seed(0)#持有种子,使得每次随机出来的数组是一样的
        normal_dataset = tf.data.Dataset.from_tensor_slices(np.random.randn(3,2,3))
        np.random.seed(0)
        map_dataset = tf.data.Dataset.from_tensor_slices(np.random.randn(3,2,3)).map(map_func=lambda x:x+1)#各数加一
        np.random.seed(0)
        flat_map_dataset = tf.data.Dataset.from_tensor_slices(np.random.randn(3,2,3)).flat_map(map_func=lambda x:tf.data.Dataset.from_tensor_slices(x))#输出的还是原来的x,但是降维了
        np.random.seed(0)
        filter_dataset = tf.data.Dataset.from_tensor_slices(np.random.randn(3,2,3)).filter(lambda x:x[0][0] > 0.8)#进行了一次过滤
    
        iterator1 = tf.data.Iterator.from_structure(normal_dataset.output_types,
                                                    normal_dataset.output_shapes)
        iterator2 = tf.data.Iterator.from_structure(map_dataset.output_types,
                                                    map_dataset.output_shapes)
        iterator3 = tf.data.Iterator.from_structure(flat_map_dataset.output_types,
                                                    flat_map_dataset.output_shapes)
        iterator4 = tf.data.Iterator.from_structure(filter_dataset.output_types,
                                                    filter_dataset.output_shapes)
    
        next_element1 = iterator1.get_next()
        next_element2 = iterator2.get_next()
        next_element3 = iterator3.get_next()
        next_element4 = iterator4.get_next()
    
        training_init_op1 = iterator1.make_initializer(normal_dataset)
        training_init_op2 = iterator2.make_initializer(map_dataset)
        training_init_op3 = iterator3.make_initializer(flat_map_dataset)
        training_init_op4 = iterator4.make_initializer(filter_dataset)
    
        print("normal:")
        sess.run(training_init_op1)
        for _ in range(3):
            print(sess.run(next_element1))
    
        print("map:")
        sess.run(training_init_op2)
        for _ in range(3):
            print(sess.run(next_element2))
    
        print("falt_map:")
        sess.run(training_init_op3)
        for _ in range(6):
            print(sess.run(next_element3))
    
        print("filter:")
        sess.run(training_init_op4)
        for _ in range(2):
            print(sess.run(next_element4))
    
     output:
     normal:
    [[ 1.76405235  0.40015721  0.97873798]
     [ 2.2408932   1.86755799 -0.97727788]]
    [[ 0.95008842 -0.15135721 -0.10321885]
     [ 0.4105985   0.14404357  1.45427351]]
    [[ 0.76103773  0.12167502  0.44386323]
     [ 0.33367433  1.49407907 -0.20515826]]
    map:
    [[ 2.76405235  1.40015721  1.97873798]
     [ 3.2408932   2.86755799  0.02272212]]
    [[ 1.95008842  0.84864279  0.89678115]
     [ 1.4105985   1.14404357  2.45427351]]
    [[ 1.76103773  1.12167502  1.44386323]
     [ 1.33367433  2.49407907  0.79484174]]
     #各数加一了
    falt_map:
    [ 1.76405235  0.40015721  0.97873798]
    [ 2.2408932   1.86755799 -0.97727788]
    [ 0.95008842 -0.15135721 -0.10321885]
    [ 0.4105985   0.14404357  1.45427351]
    [ 0.76103773  0.12167502  0.44386323]
    [ 0.33367433  1.49407907 -0.20515826]
    #这里降维成一维数组了
    filter:
    [[ 1.76405235  0.40015721  0.97873798]
     [ 2.2408932   1.86755799 -0.97727788]]
    [[ 0.95008842 -0.15135721 -0.10321885]
     [ 0.4105985   0.14404357  1.45427351]]
     #最后一个被过滤掉了

    到这里,就基本讲述了一下Dataset的输入输出方法,篇幅有限,这篇博文就到这里,之后会另开一篇,写一写数据的消费等更高级的操作!

    展开全文
  • Dataset

    千次阅读 2019-02-22 10:25:52
    Dataset 只负责数据的抽象,一次只返回一个数据或者样本 Pytorch中数据集被抽象为一个抽象类torch.utils.data.Dataset,所有的数据集都应该继承这个类,并override以下两项:    __len__:代表样本数量。len...

    Dataset                只负责数据的抽象,一次只返回一个数据或者样本

    Pytorch中数据集被抽象为一个抽象类torch.utils.data.Dataset,所有的数据集都应该继承这个类,并override以下两项:

     

        __len__:代表样本数量。len(obj)等价于obj.__len__()。

        __getitem__:返回一条数据或一个样本。obj[index]等价于obj.__getitem__。建议将节奏的图片等高负载的操作放到这里,因为多进程时会并行调用这个函数,这样做可以加速。

     

    dataset中应尽量只包含只读对象,避免修改任何可变对象。因为如果使用多进程,可变对象要加锁,但后面讲到的dataloader的设计使其难以加锁。如下面例子中的self.num可能在多进程下出问题:

     

    class BadDataset(Dataset):

     def __init__(self):

      self.datas = range(100)

      self.num = 0 # read data times

     def __getitem__(self, index):

      self.num += 1

      return self.datas[index]

     

     

    Dataloader  前面提到过,在训练神经网络时,最好是对一个batch的数据进行操作,同时还需要对数据进行shuffle和并行加速等。对此,PyTorch提供了DataLoader帮助我们实现这些功能。

     

    官方documentation

     

    Dataset负责表示数据集,它可以每次使用__getitem__返回一个样本。而torch.utils.data.Dataloader提供了对batch的处理,如shuffle等。Dataset被封装在了Dataloader中。

     

    Dataloader的构造函数如下:

     

    class torch.utils.data.DataLoader(dataset, batch_size=1, shuffle=False, sampler=None,

     batch_sampler=None, num_workers=0, collate_fn=<function default_collate>, 

     pin_memory=False, drop_last=False, timeout=0, worker_init_fn=None)

     

      

     

    部分参数解释如下:

     

        num_workers:使用的子进程数,0为不使用多进程。

            worker_init_fn: 默认为None,如果不是None,这个函数将被每个子进程以子进程id([0, num_workers - 1]之间的数)调用

        sample:采样策略,若这个参数有定义,则shuffle必须为False

        pin_memory:是否将tensor数据复制到CUDA pinned memory中,pin memory中的数据转到GPU中会快一些

        drop_last:当dataset中的数据数量不能整除batch size时,是否把最后$\text{len(dataset)} \bmod \text{batch_size} $个数据丢掉

        collate_fn:把一组samples打包成一个mini-batch的函数。可以自定义这个函数以处理损坏数据的情况(先在__getitem__函数中将这样的数据返回None,然后再在collate_fn中处理,如丢掉损坏数据or再从数据集里随机挑一张),但最好还是确保dataset里所有数据都能用。

     

    另外,Dataloader是个iterable,可以进行相关迭代操作。

    DataLoaderIter

     

    Dataset、Dataloader和DataLoaderIter是层层封装的关系,最终在内部使用DataLoaderIter进行迭代。

     

     

    https://blog.csdn.net/TH_NUM/article/details/80877687

    4 Tensor向量化数据库

    内存数据需要转为Tensor才能使用,pytorch提供了TensorDataset类可以直接对Tensor数据进行数据库封装  当x和y是pytorch的tensor时,可以方便地导入;另一个ConcatDataset,用于合并多个数据集(对于实际应用特别有用   

     

     

    train_set = torch.utils.data.TensorDataset(train_features, train_labels)
    展开全文
  • js中的dataset问题

    千次阅读 2018-08-17 16:07:14
    1.html5自定义属性及基础 html5中我们可以使用data-前缀... &lt;a href="javascript:;" data-id="...这里的data-前缀就被称为data属性,其可以通过脚本进行定义,也可以应用css属性选择器进行样式设置....
  • dataset和data set的区别

    千次阅读 2020-09-24 09:57:57
    dataset和data set的区别区别结论 参考网站:https://english.stackexchange.com/questions/2120/which-is-correct-dataset-or-data-set?answertab=active#tab-top 区别 在写英语论文的时候会遇到“数据集”这一词语...
  • 参考网站: ...区别 在写英语论文的时候会遇到“数据集”这一词语,一些英文论文使用dataset,还有一些使用的data set。采用data set的占多数。查阅了一下二者的区别,...
  • dataset

    千次阅读 2017-12-03 23:32:04
    这一篇博文收集自己要用到得数据库,持续更新,  Ranking: 【1】MovieLens Data Sets http://www.grouplens.org/node/12 【2】Yahoo! Learning to Rank Challenge ...【3】LETOR: Learni
  • c#中dataset的常用方法

    万次阅读 2019-06-25 09:49:58
  • JAVA对DataSet的操作大集合

    万次阅读 2015-08-31 11:17:30
    本博文用来收集JAVA在编程中对DataSet操作所使用的方法。 /** * 将list放map的结构 转化成dataset * @param list * @return */ private DataSet toDataSet(List list) { DataSet dataSet = new DataSet...
  • 转载博客地址: ...1)Feeding:Python代码在运行每一步时提供数据 2)从文件中读取:输入管道从TensorFlow图形的开头读取文件中的数据。 3)预加载数据:TensorFlow图中的常量或变量保存所有数
  • Spark中DataSet的基本使用

    万次阅读 2018-09-07 10:36:31
    DataSet介绍 使用alt +组合键可以查看相关类型 什么是DataSet DataSet是分布式的数据集合,Dataset提供了强类型支持,也是在RDD的每行数据加了类型约束。DataSet是在Spark1.6中添加的新的接口。它集中了RDD的优点...
  • C#遍历DataSet中数据的几种方法总结

    万次阅读 2017-04-12 21:59:13
    遍历DataSet
  • asp.NET中DataSet对象获取相应列值、行列数、列名、取出特定值这些操作的总结,具体代码如下: DataSet.Table[0].Rows[ i ][ j ] 其中i 代表第 i 行数, j 代表第 j 列数 2 DataSet.Table[0].Rows[ i ]....
  • DataSet dstmp = dsFyxx;if (dstmp.Tables.Contains("TAB_NM"))//已经存在该表的话,删除掉dstmp.Tables.Remove("TAB_NM");//创建虚拟数据表DataTable table = new DataTable("TAB_NM");//获取列集合,添加列...
  • dataset中shuffle()、repeat()、batch()用法

    万次阅读 2019-11-25 13:35:40
    import numpy as np import tensorflow as tf np.random.seed(0) x = np.random.sample((11,2)) # make a dataset from a numpy array ...dataset = tf.data.Dataset.from_tensor_slices(x) dataset = datase...
  • 获取DataSet中某行某列的数据

    万次阅读 2014-01-28 16:33:13
    LabelText = DataSet11.Tables("COMM.USERS").Rows[0]["User_Name"].tostring() LabelText = DataSet11.Tables("COMM.USERS").Rows(0).Item("user_name") Label.Text=ds.Tables(0).Rows(i).Item( "列名 ") ...
  • dataset对于操作JSON文件、NoSQL非常好用。 官方文档:
  • DataSet的排序的问题

    千次阅读 2016-01-28 14:52:01
    关于对已经绑定的DataSet的排序的问题: DataSet ds=new DataSet(); DataView dv=new DataView(); dv.Table=ds.Tables[0]; dv.Sort="CreateTime desc"; GridView.DataSource=dv; 就可以实现对dataset的排序了...
1 2 3 4 5 ... 20
收藏数 258,262
精华内容 103,304
关键字:

dataset