我正在寻找一种方法来执行与 SQL 相同的操作
SELECT DISTINCT col1, col2 FROM dataframe_table
pandas sql 比较没有任何关于
distinct
的内容。
.unique()
仅适用于单个列,所以我想我可以连接这些列,或者将它们放入列表/元组中并以这种方式进行比较,但这似乎是 pandas 应该以更原生的方式做的事情。
我是否遗漏了一些明显的东西,或者没有办法做到这一点?
drop_duplicates
方法来获取 DataFrame 中的唯一行:
In [29]: df = pd.DataFrame({'a':[1,2,1,2], 'b':[3,4,3,5]})
In [30]: df
Out[30]:
a b
0 1 3
1 2 4
2 1 3
3 2 5
In [32]: df.drop_duplicates()
Out[32]:
a b
0 1 3
1 2 4
3 2 5
如果您只想使用某些列来确定唯一性,您还可以提供
subset
关键字参数。请参阅文档字符串。
我尝试过不同的解决方案。第一个是:
a_df=np.unique(df[['col1','col2']], axis=0)
它对于非对象数据效果很好。
执行此操作并避免错误(对于对象列类型)的另一种方法是应用
drop_duplicates()
:
a_df=df.drop_duplicates(['col1','col2'])[['col1','col2']]
您也可以使用 SQL 来执行此操作,但在我的情况下运行速度非常慢:
from pandasql import sqldf
q = """SELECT DISTINCT col1, col2 FROM df;"""
pysqldf = lambda q: sqldf(q, globals())
a_df = pysqldf(q)
为了解决类似的问题,我正在使用
groupby
:
print(f"Distinct entries: {len(df.groupby(['col1', 'col2']))}")
这是否合适取决于您想要对结果做什么(在我的例子中,我只想要相当于所示的
COUNT DISTINCT
)。
我认为使用
drop duplicate
有时不会那么有用,具体取决于数据帧。
我发现了这个:
[in] df['col_1'].unique()
[out] array(['A', 'B', 'C'], dtype=object)
并为我工作!
https://riptutorial.com/pandas/example/26077/select-distinct-rows-across-dataframe
df 没有
unique
方法,如果每列的唯一值的数量相同,则以下内容将起作用:df.apply(pd.Series.unique)
但如果不是,那么您将收到错误。另一种方法是将值存储在以列名称为键的字典中:
In [111]:
df = pd.DataFrame({'a':[0,1,2,2,4], 'b':[1,1,1,2,2]})
d={}
for col in df:
d[col] = df[col].unique()
d
Out[111]:
{'a': array([0, 1, 2, 4], dtype=int64), 'b': array([1, 2], dtype=int64)}
我认为以下是最干净的方法:
df.filter(items=['Column A', 'Column B']).drop_duplicates()
您可以获取列的集合,然后从较大的集合中减去较小的集合:
distinct_values = set(df['a'])-set(df['b'])
我偶然发现这个问题,寻找相同的解决方案,但使用 Apache Spark for .NET (C#)。
以下内容对我有用(给定文件夹中的 CSV 文件列表):
string filePath = "file:///Users/me/dups/*";
var opts = new Dictionary<string, string>();
opts.Add("header", "true");
opts.Add("quote", "\"");
opts.Add("multiLine", "true");
opts.Add("sep", ",");
// load data
DataFrame df1 = spark.Read()
.Options(opts)
.Csv(filePath);
// columns to distinct on. in my case, there was 1 column I knew that was distinct per row so I listed all columns below minus that one.
Column[] columns = {
Col("MyColumn1"),
Col("MyColumn2"),
// etc.
};
var distinctCount = df1
.Select(columns)
.Distinct()
.Count();
Console.WriteLine(distinctCount);
我认为
.value_counts()
给出了最好的结果,作为奖励,你得到了最上面的计数:
df_distinct_with_counts = df[["col1", "col1"]].value_counts()
如果你不喜欢这些计数,你可以像这样删除它们(我知道有点笨拙):
df_distinct = df_distinct_with_counts.index.to_frame().reset_index(drop=True)