反变真实世界的例子

到目前为止提供的两种方法在处理大型数据集时都失败了,因为(在其他内存问题中)它们创建了 is.na(df),这将是一个与 df大小相同的对象。

如果我能在其他地方看到它的使用,那么看到一个允许我在开发过程中使用它的示例将是非常好的。

这里有两种更有内存和时间效率的方法

一般时间及记忆效率)

library(data.table)
DT <- as.data.table(df)
DT[,which(unlist(lapply(DT, function(x)!all(is.na(x))))),with=F]

使用 Filter的方法

Filter(function(x)!all(is.na(x)), df)

使用大数据的示例(30列,1e6行)

big_data <- replicate(10, data.frame(rep(NA, 1e6), sample(c(1:8,NA),1e6,T), sample(250,1e6,T)),simplify=F)
bd <- do.call(data.frame,big_data)
names(bd) <- paste0('X',seq_len(30))
DT <- as.data.table(bd)


system.time({df1 <- bd[,colSums(is.na(bd) < nrow(bd))]})
# error -- can't allocate vector of size ...
system.time({df2 <- bd[, !apply(is.na(bd), 2, all)]})
# error -- can't allocate vector of size ...
system.time({df3 <- Filter(function(x)!all(is.na(x)), bd)})
## user  system elapsed
## 0.26    0.03    0.29
system.time({DT1 <- DT[,which(unlist(lapply(DT, function(x)!all(is.na(x))))),with=F]})
## user  system elapsed
## 0.14    0.03    0.18
78406 次浏览

只是提醒你一下,这是个陷阱:

var ListOfB = new List<B>();
if(ListOfB is IEnumerable<A>)
{
// In C# 4, this branch will
// execute...
Console.Write("It is A");
}
else if (ListOfB is IEnumerable<B>)
{
// ...but in C# 3 and earlier,
// this one will execute instead.
Console.Write("It is B");
}

我希望这也能有所帮助。它可以被做成一个单独的命令,但是我发现把它分成两个命令更容易阅读。我按照下面的指示做了一个函数,工作得飞快。

无论如何,这都是可怕的代码,但是它确实存在,如果您使用这样的构造,C # 4中不断变化的行为可能会引入微妙且难以发现的 bug。

函数(DataTable){ 条目名称 = DataTable [ ,。(适用于(is.na (。(SD) ,2,all))]

假设你有一个 Person 类和一个从它派生的类,老师。您有一些以 IEnumerable<Person>作为参数的操作。在 School 类中,有一个返回 IEnumerable<Teacher>的方法。协方差允许您直接将这个结果用于采用 IEnumerable<Person>的方法,用派生程度更高的类型替换派生程度较低(更泛型)的类型。逆直觉允许您使用更通用的类型,其中指定了更派生的类型。

DataTable [ ,unlist (na.Protocol) : = NULL,with = F ] }

参见 在 MSDN 上的泛型反变

.SD 将允许限制验证表的一部分,如果你愿意,但它将采取整个表为

类别 :

public class Person
{
public string Name { get; set; }
}


public class Teacher : Person { }


public class MailingList
{
public void Add(IEnumerable<out Person> people) { ... }
}


public class School
{
public IEnumerable<Teacher> GetTeachers() { ... }
}


public class PersonNameComparer : IComparer<Person>
{
public int Compare(Person a, Person b)
{
if (a == null) return b == null ? 0 : -1;
return b == null ? 1 : Compare(a,b);
}


private int Compare(string a, string b)
{
if (a == null) return b == null ? 0 : -1;
return b == null ? 1 : a.CompareTo(b);
}
}
其中指定了更派生的类型。

用法 :

var teachers = school.GetTeachers();
var mailingList = new MailingList();


// Add() is covariant, we can use a more derived type
mailingList.Add(teachers);


// the Set<T> constructor uses a contravariant interface, IComparer<in T>,
// we can use a more generic type than required.
// See https://msdn.microsoft.com/en-us/library/8ehhxeaf.aspx for declaration syntax
var teacherSet = new SortedSet<Teachers>(teachers, new PersonNameComparer());
// Contravariance
interface IGobbler<in T> {
void gobble(T t);
}


// Since a QuadrupedGobbler can gobble any four-footed
// creature, it is OK to treat it as a donkey gobbler.
IGobbler<Donkey> dg = new QuadrupedGobbler();
dg.gobble(MyDonkey());


// Covariance
interface ISpewer<out T> {
T spew();
}


// A MouseSpewer obviously spews rodents (all mice are
// rodents), so we can treat it as a rodent spewer.
ISpewer<Rodent> rs = new MouseSpewer();
Rodent r = rs.spew();

参见 在 MSDN 上的泛型反变

类别 :

public class Person
{
public string Name { get; set; }
}


public class Teacher : Person { }


public class MailingList
{
public void Add(IEnumerable<out Person> people) { ... }
}


public class School
{
public IEnumerable<Teacher> GetTeachers() { ... }
}


public class PersonNameComparer : IComparer<Person>
{
public int Compare(Person a, Person b)
{
if (a == null) return b == null ? 0 : -1;
return b == null ? 1 : Compare(a,b);
}


private int Compare(string a, string b)
{
if (a == null) return b == null ? 0 : -1;
return b == null ? 1 : a.CompareTo(b);
}
}

为了完整..。

// Invariance
interface IHat<T> {
void hide(T t);
T pull();
}


// A RabbitHat…
IHat<Rabbit> rHat = RabbitHat();


// …cannot be treated covariantly as a mammal hat…
IHat<Mammal> mHat = rHat;      // Compiler error
// …because…
mHat.hide(new Dolphin());      // Hide a dolphin in a rabbit hat??


// It also cannot be treated contravariantly as a cottontail hat…
IHat<CottonTail> cHat = rHat;  // Compiler error
// …because…
rHat.hide(new MarshRabbit());
cHat.pull();                   // Pull a marsh rabbit out of a cottontail hat??

用法 :

var teachers = school.GetTeachers();
var mailingList = new MailingList();


// Add() is covariant, we can use a more derived type
mailingList.Add(teachers);


// the Set<T> constructor uses a contravariant interface, IComparer<in T>,
// we can use a more generic type than required.
// See https://msdn.microsoft.com/en-us/library/8ehhxeaf.aspx for declaration syntax
var teacherSet = new SortedSet<Teachers>(teachers, new PersonNameComparer());
}

In 和 out 关键字用泛型参数控制编译器对接口和委托的强制转换规则:

interface IInvariant<T> {
// This interface can not be implicitly cast AT ALL
// Used for non-readonly collections
IList<T> GetList { get; }
// Used when T is used as both argument *and* return type
T Method(T argument);
}//interface


interface ICovariant<out T> {
// This interface can be implicitly cast to LESS DERIVED (upcasting)
// Used for readonly collections
IEnumerable<T> GetList { get; }
// Used when T is used as return type
T Method();
}//interface


interface IContravariant<in T> {
// This interface can be implicitly cast to MORE DERIVED (downcasting)
// Usually means T is used as argument
void Method(T argument);
}//interface


class Casting {


IInvariant<Animal> invariantAnimal;
ICovariant<Animal> covariantAnimal;
IContravariant<Animal> contravariantAnimal;


IInvariant<Fish> invariantFish;
ICovariant<Fish> covariantFish;
IContravariant<Fish> contravariantFish;


public void Go() {


// NOT ALLOWED invariants do *not* allow implicit casting:
invariantAnimal = invariantFish;
invariantFish = invariantAnimal; // NOT ALLOWED


// ALLOWED covariants *allow* implicit upcasting:
covariantAnimal = covariantFish;
// NOT ALLOWED covariants do *not* allow implicit downcasting:
covariantFish = covariantAnimal;


// NOT ALLOWED contravariants do *not* allow implicit upcasting:
contravariantAnimal = contravariantFish;
// ALLOWED contravariants *allow* implicit downcasting
contravariantFish = contravariantAnimal;


}//method


}//class


// .NET Framework Examples:
public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable { }
public interface IEnumerable<out T> : IEnumerable { }




class Delegates {


// When T is used as both "in" (argument) and "out" (return value)
delegate T Invariant<T>(T argument);


// When T is used as "out" (return value) only
delegate T Covariant<out T>();


// When T is used as "in" (argument) only
delegate void Contravariant<in T>(T argument);


// Confusing
delegate T CovariantBoth<out T>(T argument);


// Confusing
delegate T ContravariantBoth<in T>(T argument);


// From .NET Framework:
public delegate void Action<in T>(T obj);
public delegate TResult Func<in T, out TResult>(T arg);


}//class
类委托(

来自 MSDN

//当 T 同时用作“ in”(参数)和“ out”(返回值)时

下面的代码示例显示了对反变的支持 委托 T 不变量 < T > (T 参数) ; 方法组

static object GetObject() { return null; }
static void SetObject(object obj) { }


static string GetString() { return ""; }
static void SetString(string str) { }


static void Test()
{
// Covariance. A delegate specifies a return type as object,
// but you can assign a method that returns a string.
Func<object> del = GetString;


// Contravariance. A delegate specifies a parameter type as string,
// but you can assign a method that takes an object.
Action<string> del2 = SetObject;
}
//当 T 仅用作“ out”(返回值)时

以下是我整理出来的信息,帮助我理解其中的区别

public interface ICovariant<out T> { }
public interface IContravariant<in T> { }


public class Covariant<T> : ICovariant<T> { }
public class Contravariant<T> : IContravariant<T> { }


public class Fruit { }
public class Apple : Fruit { }


public class TheInsAndOuts
{
public void Covariance()
{
ICovariant<Fruit> fruit = new Covariant<Fruit>();
ICovariant<Apple> apple = new Covariant<Apple>();


Covariant(fruit);
Covariant(apple); //apple is being upcasted to fruit, without the out keyword this will not compile
}


public void Contravariance()
{
IContravariant<Fruit> fruit = new Contravariant<Fruit>();
IContravariant<Apple> apple = new Contravariant<Apple>();


Contravariant(fruit); //fruit is being downcasted to apple, without the in keyword this will not compile
Contravariant(apple);
}


public void Covariant(ICovariant<Fruit> fruit) { }


public void Contravariant(IContravariant<Apple> apple) { }
}
委托 T 协变量 < out T > () ;

剧情回顾

ICovariant<Fruit> apple = new Covariant<Apple>(); //because it's covariant
IContravariant<Apple> fruit = new Contravariant<Fruit>(); //because it's contravariant

更新

由于以这种方式使用高阶函数的反向方法,在调用 Action时,针对 zebraAction函数(作为参数传递)调用的是派生程度更高的 Zebra实例,尽管函数本身使用派生程度较低的类型。

TInput表示向其传递方法 不那么具体的类型违规行为

public class Dog { public string Name { get; set; } }
public class Poodle : Dog { public void DoBackflip(){ System.Console.WriteLine("2nd smartest breed - woof!"); } }


public static Poodle ConvertDogToPoodle(Dog dog)
{
return new Poodle() { Name = dog.Name };
}


List<Dog> dogs = new List<Dog>() { new Dog { Name = "Truffles" }, new Dog { Name = "Fuzzball" } };
List<Poodle> poodles = dogs.ConvertAll(new Converter<Dog, Poodle>(ConvertDogToPoodle));
poodles[0].DoBackflip();

违规行为

您可以使用管理员软件包 remove_empty

library(janitor)


df %>%
remove_empty(c("rows", "cols")) #select either row or cols or both

另外,另一种 dplyr 方法

 library(dplyr)
df %>% select_if(~all(!is.na(.)))

在现实世界中,你总是可以使用动物庇护所而不是兔子庇护所,因为每次动物庇护所接待一只兔子,它就是一只动物。然而,如果你使用兔子收容所而不是动物收容所,它的工作人员可能会被老虎吃掉。

或者

df %>% select_if(colSums(!is.na(.)) == nrow(df))

如果希望只排除/保留具有一定数量缺失值的列,则这也很有用,例如。

 df %>% select_if(colSums(!is.na(.))>500)

在代码中,这意味着如果你有一个 IShelter<Animal> animals,你可以简单地编写 IShelter<Rabbit> rabbits = animals 如果,你承诺在 IShelter<T>中只使用 T作为方法参数,如下所示:

public class Contravariance
{
public class Animal { }
public class Rabbit : Animal { }


public interface IShelter<in T>
{
void Host(T thing);
}


public void NoCompileErrors()
{
IShelter<Animal> animals = null;
IShelter<Rabbit> rabbits = null;


rabbits = animals;
}
}
像这样:

public class Contravariance
{
public class Animal { }
public class Rabbit : Animal { }


public interface IShelter<in T>
{
void Host(T thing);
}


public void NoCompileErrors()
{
IShelter<Animal> animals = null;
IShelter<Rabbit> rabbits = null;


rabbits = animals;
}
}

并用一个更通用的项替换一个项,即减少方差或引入 瓦解保全方差。

并用一个更通用的项替换一个项,即减少方差或引入 瓦解保全方差。

协方差

协方差

在现实世界中,你总是可以使用兔子供应商而不是动物供应商,因为每次兔子供应商给你一只兔子,它就是一只动物。然而,如果你使用动物供应商而不是兔子供应商,你可能会被老虎吃掉。

在现实世界中,你总是可以使用兔子供应商而不是动物供应商,因为每次兔子供应商给你一只兔子,它就是一只动物。然而,如果你使用动物供应商而不是兔子供应商,你可能会被老虎吃掉。

在代码中,这意味着如果你有一个 ISupply<Rabbit> rabbits,你可以简单地编写 ISupply<Animal> animals = rabbits 如果,你承诺在 ISupply<T>中只使用 T作为方法返回值,如下所示:

public class Covariance
{
public class Animal { }
public class Rabbit : Animal { }


public interface ISupply<out T>
{
T Get();
}


public void NoCompileErrors()
{
ISupply<Animal> animals = null;
ISupply<Rabbit> rabbits = null;


animals = rabbits;
}
}

在代码中,这意味着如果你有一个 ISupply<Rabbit> rabbits,你可以简单地编写 ISupply<Animal> animals = rabbits 如果,你承诺在 ISupply<T>中只使用 T作为方法返回值,如下所示:

public class Covariance
{
public class Animal { }
public class Rabbit : Animal { }


public interface ISupply<out T>
{
T Get();
}


public void NoCompileErrors()
{
ISupply<Animal> animals = null;
ISupply<Rabbit> rabbits = null;


animals = rabbits;
}
}

并用一个更派生的项替换一个项,即增加方差或引入 合作伙伴方差。

并用一个更派生的项替换一个项,即增加方差或引入 合作伙伴方差。

总而言之,这只是你的一个 编译时可检查承诺,你会以某种方式对待一个通用类型,以保持类型安全,不会让任何人吃掉。

总而言之,这只是你的一个 编译时可检查承诺,你会以某种方式对待一个通用类型,以保持类型安全,不会让任何人吃掉。

你可能需要给 这个一个读数,让你的头脑重新思考这个问题。

你可能需要给 这个一个读数,让你的头脑重新思考这个问题。

虽然我很欣赏其他的答案,一直给我的洞察力,我认为这是如何开始容易!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;


namespace Variance
{
public class Program
{
public static void Main(string[] args)
{
IResidential<object> res1 = new House<object>();
IResidential<object> res2 = new Apartment<object>();
//IResidential<object> res2 = new Apartment<string>();
House<object> house1 = new House<object>();
//House<object> house1 = new House<string>();
IShelter<object> shl1 = new Bunker<object>();
IShelter<object> shl2 = new Bunker<string>();
IMovable<object> mvb1 = new Tank<object>();
//IMovable<object> mbv2 = new Car<string>();
IMovable<string> mbv2 = new Car<object>();
Console.WriteLine("Yes!");
}
}
    

interface IResidential<T> {}
class House<T> : IResidential<T> {}
class Apartment<T> : IResidential<T> {}
interface IShelter<out T> {}
class Bunker<T> : IShelter<T> {}
class Trench<T> : IShelter<T> {}
//class Trench<out T> : IShelter<T> {}
interface IMovable<in T> {}
class Tank<T> : IMovable<T> {}
class Car<T> : IMovable<T> {}
interface IAnimal<out U, in V>
{
U GetEnergy();
//V GetEnergy();
void SetEnergy(V energy);
//void SetEnergy(U energy);
U GetSetEnergy(V energy);
}
}