Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions cpp/src/arrow/array/array_primitive.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "arrow/array/array_base.h"
#include "arrow/type.h"
#include "arrow/util/bit_block_counter.h"
#include "arrow/util/logging.h"

namespace arrow {
Expand Down Expand Up @@ -49,6 +50,31 @@ BooleanArray::BooleanArray(int64_t length, const std::shared_ptr<Buffer>& data,
int64_t offset)
: PrimitiveArray(boolean(), length, data, null_bitmap, null_count, offset) {}

int64_t BooleanArray::false_count() const {
return this->length() - this->null_count() - this->true_count();
}

int64_t BooleanArray::true_count() const {
if (data_->null_count.load() != 0) {
DCHECK(data_->buffers[0]);
internal::BinaryBitBlockCounter bit_counter(data_->buffers[0]->data(), data_->offset,
data_->buffers[1]->data(), data_->offset,
data_->length);
int64_t count = 0;
while (true) {
internal::BitBlockCount block = bit_counter.NextAndWord();
if (block.length == 0) {
break;
}
count += block.popcount;
}
return count;
} else {
return internal::CountSetBits(data_->buffers[1]->data(), data_->offset,
data_->length);
}
}

// ----------------------------------------------------------------------
// Day time interval

Expand Down
8 changes: 8 additions & 0 deletions cpp/src/arrow/array/array_primitive.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ class ARROW_EXPORT BooleanArray : public PrimitiveArray {

bool GetView(int64_t i) const { return Value(i); }

/// \brief Return the number of false (0) values among the valid
/// values. Result is not cached.
int64_t false_count() const;

/// \brief Return the number of true (1) values among the valid
/// values. Result is not cached.
int64_t true_count() const;

protected:
using PrimitiveArray::PrimitiveArray;
};
Expand Down
27 changes: 27 additions & 0 deletions cpp/src/arrow/array/array_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,33 @@ void TestPrimitiveBuilder<PBoolean>::Check(const std::unique_ptr<BooleanBuilder>
ASSERT_EQ(0, builder->null_count());
}

TEST(TestBooleanArray, TrueCountFalseCount) {
random::RandomArrayGenerator rng(/*seed=*/0);

const int64_t length = 10000;
auto arr = rng.Boolean(length, /*true_probability=*/0.5, /*null_probability=*/0.1);

auto CheckArray = [&](const BooleanArray& values) {
int64_t expected_false = 0;
int64_t expected_true = 0;
for (int64_t i = 0; i < values.length(); ++i) {
if (values.IsValid(i)) {
if (values.Value(i)) {
++expected_true;
} else {
++expected_false;
}
}
}
ASSERT_EQ(values.true_count(), expected_true);
ASSERT_EQ(values.false_count(), expected_false);
};

CheckArray(checked_cast<const BooleanArray&>(*arr));
CheckArray(checked_cast<const BooleanArray&>(*arr->Slice(5)));
CheckArray(checked_cast<const BooleanArray&>(*arr->Slice(0, 0)));
}

TEST(TestPrimitiveAdHoc, TestType) {
Int8Builder i8(default_memory_pool());
ASSERT_TRUE(i8.type()->Equals(int8()));
Expand Down
7 changes: 7 additions & 0 deletions python/pyarrow/array.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -1158,6 +1158,13 @@ cdef class BooleanArray(Array):
"""
Concrete class for Arrow arrays of boolean data type.
"""
@property
def false_count(self):
return (<CBooleanArray*> self.ap).false_count()

@property
def true_count(self):
return (<CBooleanArray*> self.ap).true_count()


cdef class NumericArray(Array):
Expand Down
2 changes: 2 additions & 0 deletions python/pyarrow/includes/libarrow.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,8 @@ cdef extern from "arrow/api.h" namespace "arrow" nogil:

cdef cppclass CBooleanArray" arrow::BooleanArray"(CArray):
c_bool Value(int i)
int64_t false_count()
int64_t true_count()

cdef cppclass CUInt8Array" arrow::UInt8Array"(CArray):
uint8_t Value(int i)
Expand Down
7 changes: 7 additions & 0 deletions python/pyarrow/tests/test_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -1905,6 +1905,13 @@ def test_array_from_strided_bool():
assert result.equals(expected)


def test_boolean_true_count_false_count():
# ARROW-9145
arr = pa.array([True, True, None, False, None, True] * 1000)
assert arr.true_count == 3000
assert arr.false_count == 1000


def test_buffers_primitive():
a = pa.array([1, 2, None, 4], type=pa.int16())
buffers = a.buffers()
Expand Down