版本 0.16.1 (2015年5月11日)#
这是从0.16.0版本的一个小错误修复发布,包括大量错误修复、几个新功能、增强功能和性能改进。我们建议所有用户升级到这个版本。
亮点包括:
支持
CategoricalIndex
,一个基于类别的索引,详见 这里关于如何为 pandas 贡献的新章节,请参见 这里
修订了“合并、连接和串联”文档,包括图形示例以使其更容易理解每种操作,请参见 这里
新的
sample
方法用于从 Series、DataFrames 和 Panels 中抽取随机样本。请参见 这里默认的
Index
打印已更改为更统一的格式,请参见 这里BusinessHour
日期时间偏移现在已支持,请参见 这里进一步增强
.str
访问器以使字符串操作更容易,请参见 这里
v0.16.1 中的新内容
警告
在 pandas 0.17.0 中,子包 pandas.io.data
将被移除,取而代之的是一个单独安装的包 (GH 8961)。
增强功能#
CategoricalIndex#
我们引入了一个 CategoricalIndex
,这是一种新的索引对象类型,对于支持带有重复项的索引非常有用。这是一个围绕 Categorical
(在 v0.15.0 中引入)的容器,允许高效地索引和存储具有大量重复元素的索引。在 0.16.1 之前,使用 category
dtype 设置 DataFrame/Series
的索引会将其转换为常规的基于对象的 Index
。
In [1]: df = pd.DataFrame({'A': np.arange(6),
...: 'B': pd.Series(list('aabbca'))
...: .astype('category', categories=list('cab'))
...: })
...:
In [2]: df
Out[2]:
A B
0 0 a
1 1 a
2 2 b
3 3 b
4 4 c
5 5 a
In [3]: df.dtypes
Out[3]:
A int64
B category
dtype: object
In [4]: df.B.cat.categories
Out[4]: Index(['c', 'a', 'b'], dtype='object')
设置索引,将创建一个 CategoricalIndex
In [5]: df2 = df.set_index('B')
In [6]: df2.index
Out[6]: CategoricalIndex(['a', 'a', 'b', 'b', 'c', 'a'], categories=['c', 'a', 'b'], ordered=False, name='B', dtype='category')
使用 __getitem__/.iloc/.loc/.ix
进行索引与具有重复项的索引类似。索引器必须在类别中,否则操作将引发错误。
In [7]: df2.loc['a']
Out[7]:
A
B
a 0
a 1
a 5
并保留 CategoricalIndex
In [8]: df2.loc['a'].index
Out[8]: CategoricalIndex(['a', 'a', 'a'], categories=['c', 'a', 'b'], ordered=False, name='B', dtype='category')
排序将按类别顺序进行排序
In [9]: df2.sort_index()
Out[9]:
A
B
c 4
a 0
a 1
a 5
b 2
b 3
对索引进行 groupby 操作也将保留索引的性质
In [10]: df2.groupby(level=0).sum()
Out[10]:
A
B
c 4
a 6
b 5
In [11]: df2.groupby(level=0).sum().index
Out[11]: CategoricalIndex(['c', 'a', 'b'], categories=['c', 'a', 'b'], ordered=False, name='B', dtype='category')
重新索引操作将根据传递的索引器类型返回一个结果索引,这意味着传递一个列表将返回一个普通的``Index``;使用``Categorical``进行索引将返回一个``CategoricalIndex``,根据传递的``Categorical`` dtype的类别进行索引。这允许人们用不在类别中的值任意索引这些,类似于你可以重新索引任何pandas索引的方式。
In [12]: df2.reindex(['a', 'e'])
Out[12]:
A
B
a 0.0
a 1.0
a 5.0
e NaN
In [13]: df2.reindex(['a', 'e']).index
Out[13]: pd.Index(['a', 'a', 'a', 'e'], dtype='object', name='B')
In [14]: df2.reindex(pd.Categorical(['a', 'e'], categories=list('abcde')))
Out[14]:
A
B
a 0.0
a 1.0
a 5.0
e NaN
In [15]: df2.reindex(pd.Categorical(['a', 'e'], categories=list('abcde'))).index
Out[15]: pd.CategoricalIndex(['a', 'a', 'a', 'e'],
categories=['a', 'b', 'c', 'd', 'e'],
ordered=False, name='B',
dtype='category')
示例#
Series、DataFrames 和 Panels 现在有一个新方法:sample()
。该方法接受返回特定数量的行或列,或总行数或列数的分数。它还有选项用于有无替换的抽样,用于传入一列作为权重进行非均匀抽样,以及用于设置种子值以方便重复。(GH 2419)
In [1]: example_series = pd.Series([0, 1, 2, 3, 4, 5])
# When no arguments are passed, returns 1
In [2]: example_series.sample()
Out[2]:
3 3
Length: 1, dtype: int64
# One may specify either a number of rows:
In [3]: example_series.sample(n=3)
Out[3]:
2 2
1 1
0 0
Length: 3, dtype: int64
# Or a fraction of the rows:
In [4]: example_series.sample(frac=0.5)
Out[4]:
1 1
5 5
3 3
Length: 3, dtype: int64
# weights are accepted.
In [5]: example_weights = [0, 0, 0.2, 0.2, 0.2, 0.4]
In [6]: example_series.sample(n=3, weights=example_weights)
Out[6]:
2 2
4 4
3 3
Length: 3, dtype: int64
# weights will also be normalized if they do not sum to one,
# and missing values will be treated as zeros.
In [7]: example_weights2 = [0.5, 0, 0, 0, None, np.nan]
In [8]: example_series.sample(n=1, weights=example_weights2)
Out[8]:
0 0
Length: 1, dtype: int64
当应用于一个 DataFrame 时,可以传递一个列名来指定在从行中采样时的采样权重。
In [9]: df = pd.DataFrame({"col1": [9, 8, 7, 6], "weight_column": [0.5, 0.4, 0.1, 0]})
In [10]: df.sample(n=3, weights="weight_column")
Out[10]:
col1 weight_column
0 9 0.5
1 8 0.4
2 7 0.1
[3 rows x 2 columns]
字符串方法增强#
从 v0.16.0 继续,以下增强使字符串操作更容易,并与标准 Python 字符串操作更加一致。
在
Index
中添加了StringMethods``(
.str`` 访问器)(GH 9068).str
访问器现在可用于Series
和Index
。In [11]: idx = pd.Index([" jack", "jill ", " jesse ", "frank"]) In [12]: idx.str.strip() Out[12]: Index(['jack', 'jill', 'jesse', 'frank'], dtype='object')
对于
Index
上的.str
访问器,一个特殊情况是如果一个字符串方法返回bool
,.str
访问器将返回一个np.array
而不是一个布尔Index
(GH 8875)。这使得以下表达式可以自然地工作:In [13]: idx = pd.Index(["a1", "a2", "b1", "b2"]) In [14]: s = pd.Series(range(4), index=idx) In [15]: s Out[15]: a1 0 a2 1 b1 2 b2 3 Length: 4, dtype: int64 In [16]: idx.str.startswith("a") Out[16]: array([ True, True, False, False]) In [17]: s[s.index.str.startswith("a")] Out[17]: a1 0 a2 1 Length: 2, dtype: int64
以下新方法可以通过
.str
访问器访问,以将函数应用于每个值。(GH 9766, GH 9773, GH 10031, GH 10045, GH 10052)方法
capitalize()
swapcase()
normalize()
partition()
rpartition()
index()
rindex()
translate()
split
现在接受expand
关键字来指定是否扩展维度。return_type
已被弃用。(GH 9847)In [18]: s = pd.Series(["a,b", "a,c", "b,c"]) # return Series In [19]: s.str.split(",") Out[19]: 0 [a, b] 1 [a, c] 2 [b, c] Length: 3, dtype: object # return DataFrame In [20]: s.str.split(",", expand=True) Out[20]: 0 1 0 a b 1 a c 2 b c [3 rows x 2 columns] In [21]: idx = pd.Index(["a,b", "a,c", "b,c"]) # return Index In [22]: idx.str.split(",") Out[22]: Index([['a', 'b'], ['a', 'c'], ['b', 'c']], dtype='object') # return MultiIndex In [23]: idx.str.split(",", expand=True) Out[23]: MultiIndex([('a', 'b'), ('a', 'c'), ('b', 'c')], )
改进了
Index.str
的extract
和get_dummies
方法 (GH 9980)
其他增强功能#
BusinessHour
偏移现在已支持,它代表从 09:00 - 17:00 开始的营业时间,默认在BusinessDay
上。详情请参见 这里。 (GH 7905)In [24]: pd.Timestamp("2014-08-01 09:00") + pd.tseries.offsets.BusinessHour() Out[24]: Timestamp('2014-08-01 10:00:00') In [25]: pd.Timestamp("2014-08-01 07:00") + pd.tseries.offsets.BusinessHour() Out[25]: Timestamp('2014-08-01 10:00:00') In [26]: pd.Timestamp("2014-08-01 16:30") + pd.tseries.offsets.BusinessHour() Out[26]: Timestamp('2014-08-04 09:30:00')
DataFrame.diff
现在接受一个axis
参数,该参数确定差分的方向 (GH 9727)允许
clip
,clip_lower
, 和clip_upper
接受类似数组的参数作为阈值(这是从0.11.0版本回归的问题)。这些方法现在有一个axis
参数,该参数决定了如何将 Series 或 DataFrame 与阈值对齐。(GH 6966)DataFrame.mask()
和Series.mask()
现在支持与where
相同的关键字 (GH 8801)drop
函数现在可以接受errors
关键字来抑制当任何标签在目标数据中不存在时引发的ValueError
。 (GH 6736)In [27]: df = pd.DataFrame(np.random.randn(3, 3), columns=["A", "B", "C"]) In [28]: df.drop(["A", "X"], axis=1, errors="ignore") Out[28]: B C 0 -0.706771 -1.039575 1 -0.424972 0.567020 2 -1.087401 -0.673690 [3 rows x 2 columns]
添加对使用破折号分隔年份和季度的支持,例如 2014-Q1。 (GH 9688)
允许使用
astype(str)
将datetime64
或timedelta64
类型的值转换为字符串 (GH 9757)get_dummies
函数现在接受sparse
关键字。如果设置为True
,返回的DataFrame
是稀疏的,例如SparseDataFrame
。(GH 8823)Period
现在接受datetime64
作为值输入。(GH 9054)在时间定义中缺少前导零时允许 timedelta 字符串转换,即
0:00:00
与00:00:00
。 (GH 9570)允许
Panel.shift
使用axis='items'
(GH 9890)现在,如果
DataFrame
有一个MultiIndex
,尝试写入一个 Excel 文件会引发NotImplementedError
,而不是写入一个损坏的 Excel 文件。(GH 9794)允许
Categorical.add_categories
接受Series
或np.array
。(GH 9927)从
__dir__
中动态添加/删除str/dt/cat
访问器。(GH 9910)添加
normalize
作为dt
访问器方法。(GH 10047)DataFrame
和Series
现在有_constructor_expanddim
属性,作为可覆盖的构造函数用于更高维度的数据。这应该仅在确实需要时使用,参见 这里pd.lib.infer_dtype
现在在适当的情况下在 Python 3 中返回'bytes'
。(GH 10032)
API 变化#
当传递一个 ax 给
df.plot( ..., ax=ax)
时,sharex
kwarg 现在默认设置为False
。结果是 xlabels 和 xticklabels 的可见性将不再被改变。你需要自己为你的图中的正确轴进行设置,或者显式地设置sharex=True``(但这会改变图中所有轴的可见性,不仅仅是传递的那个轴!)。如果 pandas 自己创建子图(例如没有传递 ``ax
kwarg),那么默认仍然是sharex=True
,并且可见性变化会被应用。默认情况下,
read_csv
和read_table
现在会根据文件扩展名推断压缩类型。设置compression=None
以恢复之前的行为(不进行解压缩)。(GH 9770)
弃用#
Series.str.split
的return_type
关键字已被移除,取而代之的是expand
(GH 9847)
索引表示#
Index
及其子类的字符串表示形式现在已经统一。如果值较少,这些将显示单行显示;如果值较多(但少于 display.max_seq_items
),则显示多行换行显示;如果有很多项(> display.max_seq_items
),将显示截断显示(数据的头和尾)。MultiIndex
的格式保持不变(多行换行显示)。显示宽度响应选项 display.max_seq_items
,默认值为 100。(GH 6482)
之前的操作
In [2]: pd.Index(range(4), name='foo')
Out[2]: Int64Index([0, 1, 2, 3], dtype='int64')
In [3]: pd.Index(range(104), name='foo')
Out[3]: Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, ...], dtype='int64')
In [4]: pd.date_range('20130101', periods=4, name='foo', tz='US/Eastern')
Out[4]:
<class 'pandas.tseries.index.DatetimeIndex'>
[2013-01-01 00:00:00-05:00, ..., 2013-01-04 00:00:00-05:00]
Length: 4, Freq: D, Timezone: US/Eastern
In [5]: pd.date_range('20130101', periods=104, name='foo', tz='US/Eastern')
Out[5]:
<class 'pandas.tseries.index.DatetimeIndex'>
[2013-01-01 00:00:00-05:00, ..., 2013-04-14 00:00:00-04:00]
Length: 104, Freq: D, Timezone: US/Eastern
新行为
In [29]: pd.set_option("display.width", 80)
In [30]: pd.Index(range(4), name="foo")
Out[30]: RangeIndex(start=0, stop=4, step=1, name='foo')
In [31]: pd.Index(range(30), name="foo")
Out[31]: RangeIndex(start=0, stop=30, step=1, name='foo')
In [32]: pd.Index(range(104), name="foo")
Out[32]: RangeIndex(start=0, stop=104, step=1, name='foo')
In [33]: pd.CategoricalIndex(["a", "bb", "ccc", "dddd"], ordered=True, name="foobar")
Out[33]: CategoricalIndex(['a', 'bb', 'ccc', 'dddd'], categories=['a', 'bb', 'ccc', 'dddd'], ordered=True, dtype='category', name='foobar')
In [34]: pd.CategoricalIndex(["a", "bb", "ccc", "dddd"] * 10, ordered=True, name="foobar")
Out[34]:
CategoricalIndex(['a', 'bb', 'ccc', 'dddd', 'a', 'bb', 'ccc', 'dddd', 'a',
'bb', 'ccc', 'dddd', 'a', 'bb', 'ccc', 'dddd', 'a', 'bb',
'ccc', 'dddd', 'a', 'bb', 'ccc', 'dddd', 'a', 'bb', 'ccc',
'dddd', 'a', 'bb', 'ccc', 'dddd', 'a', 'bb', 'ccc', 'dddd',
'a', 'bb', 'ccc', 'dddd'],
categories=['a', 'bb', 'ccc', 'dddd'], ordered=True, dtype='category', name='foobar')
In [35]: pd.CategoricalIndex(["a", "bb", "ccc", "dddd"] * 100, ordered=True, name="foobar")
Out[35]:
CategoricalIndex(['a', 'bb', 'ccc', 'dddd', 'a', 'bb', 'ccc', 'dddd', 'a',
'bb',
...
'ccc', 'dddd', 'a', 'bb', 'ccc', 'dddd', 'a', 'bb', 'ccc',
'dddd'],
categories=['a', 'bb', 'ccc', 'dddd'], ordered=True, dtype='category', name='foobar', length=400)
In [36]: pd.date_range("20130101", periods=4, name="foo", tz="US/Eastern")
Out[36]:
DatetimeIndex(['2013-01-01 00:00:00-05:00', '2013-01-02 00:00:00-05:00',
'2013-01-03 00:00:00-05:00', '2013-01-04 00:00:00-05:00'],
dtype='datetime64[ns, US/Eastern]', name='foo', freq='D')
In [37]: pd.date_range("20130101", periods=25, freq="D")
Out[37]:
DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
'2013-01-05', '2013-01-06', '2013-01-07', '2013-01-08',
'2013-01-09', '2013-01-10', '2013-01-11', '2013-01-12',
'2013-01-13', '2013-01-14', '2013-01-15', '2013-01-16',
'2013-01-17', '2013-01-18', '2013-01-19', '2013-01-20',
'2013-01-21', '2013-01-22', '2013-01-23', '2013-01-24',
'2013-01-25'],
dtype='datetime64[ns]', freq='D')
In [38]: pd.date_range("20130101", periods=104, name="foo", tz="US/Eastern")
Out[38]:
DatetimeIndex(['2013-01-01 00:00:00-05:00', '2013-01-02 00:00:00-05:00',
'2013-01-03 00:00:00-05:00', '2013-01-04 00:00:00-05:00',
'2013-01-05 00:00:00-05:00', '2013-01-06 00:00:00-05:00',
'2013-01-07 00:00:00-05:00', '2013-01-08 00:00:00-05:00',
'2013-01-09 00:00:00-05:00', '2013-01-10 00:00:00-05:00',
...
'2013-04-05 00:00:00-04:00', '2013-04-06 00:00:00-04:00',
'2013-04-07 00:00:00-04:00', '2013-04-08 00:00:00-04:00',
'2013-04-09 00:00:00-04:00', '2013-04-10 00:00:00-04:00',
'2013-04-11 00:00:00-04:00', '2013-04-12 00:00:00-04:00',
'2013-04-13 00:00:00-04:00', '2013-04-14 00:00:00-04:00'],
dtype='datetime64[ns, US/Eastern]', name='foo', length=104, freq='D')
性能提升#
错误修复#
在
DataFrame.plot()
的图例中标签未正确显示的错误,传递label=
参数有效,并且 Series 索引不再被改变。(GH 9542)当帧长度为零时,json序列化中的错误导致段错误。(GH 9805)
read_csv
中缺少尾随分隔符会导致段错误的问题。(GH 5664)在追加时保留索引名称的错误 (GH 9862)
scatter_matrix
中的错误绘制了意外的轴刻度标签 (GH 5662)修复了
StataWriter
中的错误,该错误在保存时导致输入DataFrame
发生变化 (GH 9795)。transform
中的错误导致当存在空条目并且使用快速聚合器时长度不匹配 (GH 9697)equals
中的错误导致当块顺序不同时出现假阴性 (GH 9330)在多个
pd.Grouper
分组中存在一个非时间基准的错误 (GH 10063)在读取带有时区信息的postgres表时,
read_sql_table
出现错误 (GH 7139)DataFrame
切片中的错误可能不会保留元数据 (GH 9776)在固定的
HDFStore
中TimdeltaIndex
未正确序列化的错误 (GH 9635)TimedeltaIndex
构造函数在给定另一个TimedeltaIndex
作为数据时忽略name
的错误 (GH 10025)。在
DataFrameFormatter._get_formatted_index
中存在一个错误,未将max_colwidth
应用于DataFrame
索引 (GH 7856)在只读 ndarray 数据源中
.loc
的错误 (GH 10043)groupby.apply()
中的一个错误,如果传递的用户定义函数仅返回 ``None``(对于所有输入),则会引发该错误。(GH 9685)在pytables测试中始终使用临时文件 (GH 9992)
当
DataFrame
包含非数字列时,DataFrame.plot(kind="hist")
中的错误导致TypeError
(GH 9853)在
DatetimeIndex
的DataFrame
重复绘图时可能引发TypeError
的错误 (GH 9852)setup.py
中的错误允许不兼容的 cython 版本进行构建 (GH 9827)绘图中的错误
secondary_y
错误地将right_ax
属性递归地附加到指定自身的次要轴上。 (GH 9861)在类型为
Datetime
或Timedelta
的空Series
中Series.quantile
的错误 (GH 9675)where
中的错误导致在需要向上转换时产生不正确的结果 (GH 9731)FloatArrayFormatter
中的一个错误,其中在给定 display.precision 的情况下,以十进制格式显示“小”浮点的决策边界偏差了一个数量级 (GH 9764)修复了
DataFrame.plot()
在同时传递color
和style
关键字且 style 字符串中没有颜色符号时引发错误的问题 (GH 9671)在将类似列表的对象与
Index
结合时不显示DeprecationWarning
(GH 10083)在使用
skip_rows
参数时,如果存在空白行,read_csv
和read_table
中存在错误。(GH 9832)read_csv()
中的错误将index_col=True
解释为1
(GH 9798)使用
==
进行索引相等比较时,由于 Index/MultiIndex 类型不兼容导致的错误 (GH 9785)SparseDataFrame
不能接受nan
作为列名的错误 (GH 8822)to_msgpack
和read_msgpack
中的 zlib 和 blosc 压缩支持存在问题 (GH 9783)错误
GroupBy.size
如果按TimeGrouper
分组,则无法正确附加索引名称 (GH 9925)由于
length_of_indexer
返回错误结果,导致切片赋值中出现异常 (GH 9995)csv 解析器中的错误导致跳过以初始空白字符加一个非空白字符开头的行。(GH 9710)
C csv 解析器中的错误导致当数据以换行符后跟空格开始时出现虚假的 NaNs。(GH 10022)
当按
Categorical
分组时,导致具有空组的元素溢出到最终组中的错误 (GH 9603)在空数据框上 .iloc 和 .loc 行为不一致的错误 (GH 9964)
在
TimedeltaIndex
上的无效属性访问中,错误地引发了ValueError
而不是AttributeError
(GH 9680)在分类数据与标量进行不等比较时出现的错误,该标量不在类别中(例如
Series(Categorical(list("abc"), ordered=True)) > "d"
。这返回了所有元素的False
,但现在会引发TypeError
。相等比较现在也会为==
返回False
,为!=
返回True
。(GH 9848)当右侧是一个字典时,DataFrame
__setitem__
中的错误 (GH 9874)当
where
的 dtype 是datetime64/timedelta64
时,但另一个的 dtype 不是 (GH 9804)MultiIndex.sortlevel()
中的错误导致 Unicode 层名中断 (GH 9856)groupby.transform
错误地强制输出数据类型与输入数据类型匹配的错误。(GH 9807)当
columns
参数被设置,且data
是一个空列表时,DataFrame
构造函数中的错误 (GH 9939)如果所有值都小于1,使用
log=True
的条形图会出现TypeError
错误 (GH 9905)水平条形图中的错误忽略
log=True
(GH 9905)在包含
Decimal
类型值的数据框除以另一个Decimal
时会引发错误的 Bug。(GH 9787)使用 DataFrames asfreq 会移除索引名称的错误。(GH 9885)
在重采样 BM/BQ 时导致额外索引点的问题 (GH 9756)
在
AbstractHolidayCalendar
中更改了缓存,使其在实例级别而不是类级别,因为后者可能导致意外行为。(GH 9552)修复了 MultiIndexed 数据框的固定 latex 输出 (GH 9778)
使用
DataFrame.loc
设置空范围时导致异常的错误 (GH 9596)在子图和共享轴的情况下隐藏刻度标签的错误,当向现有轴网格添加新图时 (GH 9158)
当按分类变量分组时,
transform
和filter
中的错误 (GH 9921)当组数和数据类型与输入索引相同时,
transform
中的错误 (GH 9700)Google BigQuery 连接器现在按每个方法导入依赖项。(GH 9713)
更新了 BigQuery 连接器,不再使用已弃用的
oauth2client.tools.run()
(GH 8327)子类化的
DataFrame
中的错误。在切片或子集化时,它可能不会返回正确的类。(GH 9632)在
.median()
中存在一个错误,其中非浮点空值未被正确处理 (GH 10040)在 Series.fillna() 中存在一个错误,当给定一个可数值转换的字符串时会引发异常 (GH 10092)
贡献者#
共有58人为此版本贡献了补丁。名字后面带有“+”的人首次贡献了补丁。
Alfonso MHC +
Andy Hayden
Artemy Kolchinsky
Chris Gilmer +
Chris Grinolds +
Dan Birken
David BROCHART +
David Hirschfeld +
David Stephens
Dr. Leo +
Evan Wright +
Frans van Dunné +
Hatem Nassrat +
Henning Sperr +
Hugo Herter +
Jan Schulz
Jeff Blackburne +
Jeff Reback
Jim Crist +
Jonas Abernot +
Joris Van den Bossche
Kerby Shedden
Leo Razoumov +
Manuel Riel +
Mortada Mehyar
Nick Burns +
Nick Eubank +
Olivier Grisel
Phillip Cloud
Pietro Battiston
Roy Hyunjin Han
Sam Zhang +
Scott Sanderson +
Sinhrks +
Stephan Hoyer
Tiago Antao
Tom Ajamian +
Tom Augspurger
Tomaz Berisa +
Vikram Shirgur +
Vladimir Filimonov
William Hogman +
Yasin A +
Younggun Kim +
behzad nouri
dsm054
floydsoft +
flying-sheep +
gfr +
jnmclarty
jreback
ksanghai +
lucas +
mschmohl +
ptype +
rockg
scls19fr +
sinhrks